diff options
Diffstat (limited to 'experimental/tqtinterface/qt4/src/kernel/tqpaintdevice_x11.cpp')
-rw-r--r-- | experimental/tqtinterface/qt4/src/kernel/tqpaintdevice_x11.cpp | 1746 |
1 files changed, 1746 insertions, 0 deletions
diff --git a/experimental/tqtinterface/qt4/src/kernel/tqpaintdevice_x11.cpp b/experimental/tqtinterface/qt4/src/kernel/tqpaintdevice_x11.cpp new file mode 100644 index 000000000..243260741 --- /dev/null +++ b/experimental/tqtinterface/qt4/src/kernel/tqpaintdevice_x11.cpp @@ -0,0 +1,1746 @@ +/**************************************************************************** +** +** Implementation of TQPaintDevice class for X11 +** +** Created : 940721 +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of the kernel module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tqpaintdevice.h" +#include "tqpaintdevicemetrics.h" +#include "tqpainter.h" +#include "tqwidget.h" +#include "tqbitmap.h" +#include "tqapplication.h" +#include "tqt_x11_p.h" + +#ifdef USE_QT4 + +// +// Some global variables - these are initialized by TQColor::initialize() +// + +Display *TQPaintDevice::x_appdisplay = 0; +int TQPaintDevice::x_appscreen; + +int TQPaintDevice::x_appdepth; +int TQPaintDevice::x_appcells; +TQt::HANDLE TQPaintDevice::x_approotwindow; +TQt::HANDLE TQPaintDevice::x_appcolormap; +bool TQPaintDevice::x_appdefcolormap; +void *TQPaintDevice::x_appvisual; +bool TQPaintDevice::x_appdefvisual; + +// ### in 4.0, remove the above, and use the below +int *TQPaintDevice::x_appdepth_arr; +int *TQPaintDevice::x_appcells_arr; +TQt::HANDLE *TQPaintDevice::x_approotwindow_arr; +TQt::HANDLE *TQPaintDevice::x_appcolormap_arr; +bool *TQPaintDevice::x_appdefcolormap_arr; +void **TQPaintDevice::x_appvisual_arr; +bool *TQPaintDevice::x_appdefvisual_arr; + +/*! + Constructs a paint tqdevice with internal flags \a devflags. This + constructor can be invoked only from TQPaintDevice subclasses. +*/ + +TQPaintDevice::TQPaintDevice( uint devflags ) +{ + if ( !tqApp ) { // global constructor +#if defined(TQT_CHECK_STATE) + qFatal( "TQPaintDevice: Must construct a TQApplication before a " + "TQPaintDevice" ); +#endif + return; + } + + // [FIXME] + printf("[WARNING] TQPaintDevice::TQPaintDevice( uint devflags ) unimplemented\n\r"); +// devFlags = devflags; +// painters = 0; +// hd = 0; +// rendhd = 0; +// x11Data = 0; +} + +/*! + Returns the window system handle of the paint tqdevice, for + low-level access. Using this function is not portable. + + The HANDLE type varies with platform; see \c tqpaintdevice.h and + \c tqwindowdefs.h for details. + + \sa x11Display() +*/ +TQt::HANDLE TQPaintDevice::handle() const +{ +// return hd; + + // [FIXME] + printf("[WARNING] TQPaintDevice::handle() const unimplemented\n\r"); + return 0; +} + +/*! + Returns the window system handle of the paint tqdevice for XRender + support. Use of this function is not portable. This function will + return 0 if XRender support is not compiled into TQt, if the + XRender extension is not supported on the X11 display, or if the + handle could not be created. +*/ +TQt::HANDLE TQPaintDevice::x11RenderHandle() const +{ +// #ifndef TQT_NO_XFTFREETYPE +// return rendhd ? XftDrawPicture( (XftDraw *) rendhd ) : 0; +// #else +// return 0; +// #endif // TQT_NO_XFTFREETYPE + + // [FIXME] + printf("[WARNING] TQPaintDevice::x11RenderHandle() const unimplemented\n\r"); + return 0; +} + +/*! + \relates QPaintDevice + + Returns the QX11Info structure for the \a pd paint device. 0 is + returned if it can't be obtained. +*/ +const Q_GUI_EXPORT QX11Info *qt_x11Info(const QPaintDevice *pd) +{ + if (!pd) return 0; + if (pd->devType() == QInternal::Widget) + return &static_cast<const QWidget *>(pd)->x11Info(); + else if (pd->devType() == QInternal::Pixmap) + return &static_cast<const QPixmap *>(pd)->x11Info(); + return 0; +} + +Display *TQPaintDevice::x11Display() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->display(); + return QX11Info::display(); +} + +int TQPaintDevice::x11Screen() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->screen(); + return QX11Info::appScreen(); +} + +void *TQPaintDevice::x11Visual() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->visual(); + return QX11Info::appVisual(); +} + +int TQPaintDevice::x11Depth() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->depth(); + return QX11Info::appDepth(); +} + +int TQPaintDevice::x11Cells() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->cells(); + return QX11Info::appCells(); +} + +Qt::HANDLE TQPaintDevice::x11Colormap() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->colormap(); + return QX11Info::appColormap(); +} + +bool TQPaintDevice::x11DefaultColormap() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->defaultColormap(); + return QX11Info::appDefaultColormap(); +} + +bool TQPaintDevice::x11DefaultVisual() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->defaultVisual(); + return QX11Info::appDefaultVisual(); +} + +void TQPaintDevice::x11SetAppDpiX(int dpi, int screen) +{ + QX11Info::setAppDpiX(dpi, screen); +} + +void TQPaintDevice::x11SetAppDpiY(int dpi, int screen) +{ + QX11Info::setAppDpiY(dpi, screen); +} + +int TQPaintDevice::x11AppDpiX(int screen) +{ + return QX11Info::appDpiX(screen); +} + +int TQPaintDevice::x11AppDpiY(int screen) +{ + return QX11Info::appDpiY(screen); +} + +/*! + \relates TQPaintDevice + + Copies a block of pixels from \a src to \a dst, perhaps merging + each pixel according to the \link TQt::RasterOp raster operation \endlink + \a rop. \a sx, \a sy + is the top-left pixel in \a src (0, 0) by default, \a dx, \a dy is + the top-left position in \a dst and \a sw, \a sh is the size of + the copied block (all of \a src by default). + + The most common values for \a rop are CopyROP and XorROP; the \l + TQt::RasterOp documentation defines all the possible values. + + If \a ignoreMask is FALSE (the default) and \a src is a + masked TQPixmap, the entire blit is masked by \a{src}->tqmask(). + + If \a src, \a dst, \a sw or \a sh is 0, bitBlt() does nothing. If + \a sw or \a sh is negative bitBlt() copies starting at \a sx (and + respectively, \a sy) and ending at the right end (respectively, + bottom) of \a src. + + \a src must be a TQWidget or TQPixmap. You cannot blit from a + TQPrinter, for example. bitBlt() does nothing if you attempt to + blit from an unsupported tqdevice. + + bitBlt() does nothing if \a src has a greater depth than \e dst. + If you need to for example, draw a 24-bit pixmap on an 8-bit + widget, you must use drawPixmap(). +*/ + +void bitBlt( TQPaintDevice *dst, int dx, int dy, + const TQPaintDevice *src, int sx, int sy, int sw, int sh, + TQt::RasterOp rop, bool ignoreMask ) +{ +// [FIXME] Implement this for Qt4! +printf("[WARNING] bitBlt( TQPaintDevice *dst, int dx, int dy, const TQPaintDevice *src, int sx, int sy, int sw, int sh, TQt::RasterOp rop, bool ignoreMask ) unimplemented\n\r"); + +// if ( !src || !dst ) { +// #if defined(TQT_CHECK_NULL) +// TQ_ASSERT( src != 0 ); +// TQ_ASSERT( dst != 0 ); +// #endif +// return; +// } +// if ( !src->handle() || src->isExtDev() ) +// return; +// +// TQPaintDevice *pdev = TQPainter::redirect( dst ); +// if ( pdev ) +// dst = pdev; +// +// int ts = src->devType(); // from tqdevice type +// int td = dst->devType(); // to tqdevice type +// Display *dpy = src->x11Display(); +// +// if ( sw <= 0 ) { // special width +// if ( sw < 0 ) +// sw = src->metric( TQPaintDeviceMetrics::PdmWidth ) - sx; +// else +// return; +// } +// if ( sh <= 0 ) { // special height +// if ( sh < 0 ) +// sh = src->metric( TQPaintDeviceMetrics::PdmHeight ) - sy; +// else +// return; +// } +// +// if ( dst->paintingActive() && dst->isExtDev() ) { +// TQPixmap *pm; // output to picture/printer +// bool tmp_pm = TRUE; +// if ( ts == TQInternal::Pixmap ) { +// pm = (TQPixmap*)src; +// if ( sx != 0 || sy != 0 || +// sw != pm->width() || sh != pm->height() || ignoreMask ) { +// TQPixmap *tmp = new TQPixmap( sw, sh, pm->depth() ); +// bitBlt( tmp, 0, 0, pm, sx, sy, sw, sh, TQt::CopyROP, TRUE ); +// if ( pm->tqmask() && !ignoreMask ) { +// TQBitmap tqmask( sw, sh ); +// bitBlt( &tqmask, 0, 0, pm->tqmask(), sx, sy, sw, sh, +// TQt::CopyROP, TRUE ); +// tmp->setMask( tqmask ); +// } +// pm = tmp; +// } else { +// tmp_pm = FALSE; +// } +// } else if ( ts == TQInternal::Widget ) {// bitBlt to temp pixmap +// pm = new TQPixmap( sw, sh ); +// TQ_CHECK_PTR( pm ); +// bitBlt( pm, 0, 0, src, sx, sy, sw, sh ); +// } else { +// #if defined(TQT_CHECK_RANGE) +// qWarning( "bitBlt: Cannot bitBlt from tqdevice" ); +// #endif +// return; +// } +// TQPDevCmdParam param[3]; +// TQRect r(dx, dy, pm->width(), pm->height()); +// param[0].rect = &r; +// param[1].pixmap = pm; +// dst->cmd( TQPaintDevice::PdcDrawPixmap, 0, param ); +// if ( tmp_pm ) +// delete pm; +// return; +// } +// +// switch ( ts ) { +// case TQInternal::Widget: +// case TQInternal::Pixmap: +// case TQInternal::System: // OK, can blt from these +// break; +// default: +// #if defined(TQT_CHECK_RANGE) +// qWarning( "bitBlt: Cannot bitBlt from tqdevice type %x", ts ); +// #endif +// return; +// } +// switch ( td ) { +// case TQInternal::Widget: +// case TQInternal::Pixmap: +// case TQInternal::System: // OK, can blt to these +// break; +// default: +// #if defined(TQT_CHECK_RANGE) +// qWarning( "bitBlt: Cannot bitBlt to tqdevice type %x", td ); +// #endif +// return; +// } +// +// static const short ropCodes[] = { // ROP translation table +// GXcopy, GXor, GXxor, GXandInverted, +// GXcopyInverted, GXorInverted, GXequiv, GXand, +// GXinvert, GXclear, GXset, GXnoop, +// GXandReverse, GXorReverse, GXnand, GXnor +// }; +// if ( rop > TQt::LastROP ) { +// #if defined(TQT_CHECK_RANGE) +// qWarning( "bitBlt: Invalid ROP code" ); +// #endif +// return; +// } +// +// if ( dst->handle() == 0 ) { +// #if defined(TQT_CHECK_NULL) +// qWarning( "bitBlt: Cannot bitBlt to tqdevice" ); +// #endif +// return; +// } +// +// bool mono_src; +// bool mono_dst; +// bool include_inferiors = FALSE; +// bool graphics_exposure = FALSE; +// TQPixmap *src_pm; +// TQBitmap *tqmask; +// +// if ( ts == TQInternal::Pixmap ) { +// src_pm = (TQPixmap*)src; +// if ( src_pm->x11Screen() != dst->x11Screen() ) +// src_pm->x11SetScreen( dst->x11Screen() ); +// mono_src = src_pm->depth() == 1; +// tqmask = ignoreMask ? 0 : src_pm->data->tqmask; +// } else { +// src_pm = 0; +// mono_src = FALSE; +// tqmask = 0; +// include_inferiors = ((TQWidget*)src)->testWFlags(TQt::WPaintUnclipped); +// graphics_exposure = td == TQInternal::Widget; +// } +// if ( td == TQInternal::Pixmap ) { +// if ( dst->x11Screen() != src->x11Screen() ) +// ((TQPixmap*)dst)->x11SetScreen( src->x11Screen() ); +// mono_dst = ((TQPixmap*)dst)->depth() == 1; +// ((TQPixmap*)dst)->detach(); // changes shared pixmap +// } else { +// mono_dst = FALSE; +// include_inferiors = include_inferiors || +// ((TQWidget*)dst)->testWFlags(TQt::WPaintUnclipped); +// } +// +// if ( mono_dst && !mono_src ) { // dest is 1-bit pixmap, source is not +// #if defined(TQT_CHECK_RANGE) +// qWarning( "bitBlt: Incompatible destination pixmap" ); +// #endif +// return; +// } +// +// #ifndef TQT_NO_XRENDER +// if (src_pm && !mono_src && src_pm->data->alphapm && !ignoreMask ) { +// // use RENDER to do the blit +// TQPixmap *alpha = src_pm->data->alphapm; +// if (src->x11RenderHandle() && +// alpha->x11RenderHandle() && +// dst->x11RenderHandle()) { +// XRenderPictureAttributes pattr; +// ulong pictqmask = 0; +// if (include_inferiors) { +// pattr.subwindow_mode = IncludeInferiors; +// pictqmask |= CPSubwindowMode; +// } +// if (graphics_exposure) { +// pattr.graphics_exposures = TRUE; +// pictqmask |= CPGraphicsExposure; +// } +// if (pictqmask) +// XRenderChangePicture(dpy, dst->x11RenderHandle(), pictqmask, &pattr); +// XRenderComposite(dpy, PictOpOver, src->x11RenderHandle(), +// alpha->x11RenderHandle(), dst->x11RenderHandle(), +// sx, sy, sx, sy, dx, dy, sw, sh); +// // restore attributes +// pattr.subwindow_mode = ClipByChildren; +// pattr.graphics_exposures = FALSE; +// if (pictqmask) +// XRenderChangePicture(dpy, dst->x11RenderHandle(), pictqmask, &pattr); +// return; +// } +// } +// #endif +// +// GC gc; +// +// if ( tqmask && !mono_src ) { // fast masked blt +// bool temp_gc = FALSE; +// if ( tqmask->data->maskgc ) { +// gc = (GC)tqmask->data->maskgc; // we have a premade tqmask GC +// } else { +// if ( FALSE && src_pm->optimization() == TQPixmap::NormalOptim ) { // #### cache disabled +// // Compete for the global cache +// gc = cache_mask_gc( dpy, dst->handle(), +// tqmask->data->ser_no, +// tqmask->handle() ); +// } else { +// // Create a new tqmask GC. If BestOptim, we store the tqmask GC +// // with the tqmask (not at the pixmap). This way, many pixmaps +// // which have a common tqmask will be optimized at no extra cost. +// gc = XCreateGC( dpy, dst->handle(), 0, 0 ); +// XSetGraphicsExposures( dpy, gc, False ); +// XSetClipMask( dpy, gc, tqmask->handle() ); +// if ( src_pm->optimization() == TQPixmap::BestOptim ) { +// tqmask->data->maskgc = gc; +// } else { +// temp_gc = TRUE; +// } +// } +// } +// XSetClipOrigin( dpy, gc, dx-sx, dy-sy ); +// if ( rop != TQt::CopyROP ) // use non-default ROP code +// XSetFunction( dpy, gc, ropCodes[rop] ); +// if ( include_inferiors ) { +// XSetSubwindowMode( dpy, gc, IncludeInferiors ); +// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, +// dx, dy ); +// XSetSubwindowMode( dpy, gc, ClipByChildren ); +// } else { +// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, +// dx, dy ); +// } +// +// if ( temp_gc ) // delete temporary GC +// XFreeGC( dpy, gc ); +// else if ( rop != TQt::CopyROP ) // restore ROP +// XSetFunction( dpy, gc, GXcopy ); +// return; +// } +// +// gc = qt_xget_temp_gc( dst->x11Screen(), mono_dst ); // get a reusable GC +// +// if ( rop != TQt::CopyROP ) // use non-default ROP code +// XSetFunction( dpy, gc, ropCodes[rop] ); +// +// if ( mono_src && mono_dst && src == dst ) { // dst and src are the same bitmap +// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, dx, dy ); +// } else if ( mono_src ) { // src is bitmap +// XGCValues gcvals; +// ulong valtqmask = GCBackground | GCForeground | GCFillStyle | +// GCStipple | GCTileStipXOrigin | GCTileStipYOrigin; +// if ( td == TQInternal::Widget ) { // set GC colors +// TQWidget *w = (TQWidget *)dst; +// gcvals.background = w->backgroundColor().pixel( dst->x11Screen() ); +// gcvals.foreground = w->foregroundColor().pixel( dst->x11Screen() ); +// if ( include_inferiors ) { +// valtqmask |= GCSubwindowMode; +// gcvals.subwindow_mode = IncludeInferiors; +// } +// } else if ( mono_dst ) { +// gcvals.background = 0; +// gcvals.foreground = 1; +// } else { +// gcvals.background = TQt::white.pixel( dst->x11Screen() ); +// gcvals.foreground = TQt::black.pixel( dst->x11Screen() ); +// } +// +// gcvals.fill_style = FillOpaqueStippled; +// gcvals.stipple = src->handle(); +// gcvals.ts_x_origin = dx - sx; +// gcvals.ts_y_origin = dy - sy; +// +// bool cliptqmask = FALSE; +// if ( tqmask ) { +// if ( ((TQPixmap*)src)->data->selfmask ) { +// gcvals.fill_style = FillStippled; +// } else { +// XSetClipMask( dpy, gc, tqmask->handle() ); +// XSetClipOrigin( dpy, gc, dx-sx, dy-sy ); +// cliptqmask = TRUE; +// } +// } +// +// XChangeGC( dpy, gc, valtqmask, &gcvals ); +// XFillRectangle( dpy,dst->handle(), gc, dx, dy, sw, sh ); +// +// valtqmask = GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; +// gcvals.fill_style = FillSolid; +// gcvals.ts_x_origin = 0; +// gcvals.ts_y_origin = 0; +// if ( include_inferiors ) { +// valtqmask |= GCSubwindowMode; +// gcvals.subwindow_mode = ClipByChildren; +// } +// XChangeGC( dpy, gc, valtqmask, &gcvals ); +// +// if ( cliptqmask ) { +// XSetClipOrigin( dpy, gc, 0, 0 ); +// XSetClipMask( dpy, gc, None ); +// } +// +// } else { // src is pixmap/widget +// +// if ( graphics_exposure ) // widget to widget +// XSetGraphicsExposures( dpy, gc, True ); +// if ( include_inferiors ) { +// XSetSubwindowMode( dpy, gc, IncludeInferiors ); +// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, +// dx, dy ); +// XSetSubwindowMode( dpy, gc, ClipByChildren ); +// } else { +// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, +// dx, dy ); +// } +// if ( graphics_exposure ) // reset graphics exposure +// XSetGraphicsExposures( dpy, gc, False ); +// } +// +// if ( rop != TQt::CopyROP ) // restore ROP +// XSetFunction( dpy, gc, GXcopy ); +} + +/*! + Internal virtual function that interprets drawing commands from + the painter. + + Implemented by subclasses that have no direct support for drawing + graphics (external paint tqdevices, for example, TQPicture). +*/ + +bool TQPaintDevice::cmd( int, TQPainter *, TQPDevCmdParam * ) +{ +#if defined(TQT_CHECK_STATE) + qWarning( "TQPaintDevice::cmd: Device has no command interface" ); +#endif + return FALSE; +} + +// Reimplemented QPaintEngine methods +// These need to call their equivalent Qt3 cmd methods +bool TQPaintDeviceEngineTranslator::begin(QPaintDevice* qpd) { + printf("[WARNING] TQPaintDeviceEngineTranslator::begin() unimplemented\n\r"); +} + +bool TQPaintDeviceEngineTranslator::end() { + printf("[WARNING] TQPaintDeviceEngineTranslator::end() unimplemented\n\r"); +} + +void TQPaintDeviceEngineTranslator::updateState(const QPaintEngineState& qpes) { + printf("[WARNING] TQPaintDeviceEngineTranslator::updateState() unimplemented\n\r"); +} + +void TQPaintDeviceEngineTranslator::drawPixmap(const QRectF& rect1, const QPixmap& pixmap, const QRectF& rect2) { + printf("[WARNING] TQPaintDeviceEngineTranslator::drawPixmap() unimplemented\n\r"); +} + +QPaintEngine::Type TQPaintDeviceEngineTranslator::type() const { + printf("[WARNING] TQPaintDeviceEngineTranslator::type() unimplemented\n\r"); + return QPaintEngine::X11; +} + +#else // USE_QT4 + +/*! + \class TQPaintDevice tqpaintdevice.h + \brief The TQPaintDevice class is the base class of objects that + can be painted. + + \ingroup graphics + \ingroup images + + A paint tqdevice is an abstraction of a two-dimensional space that + can be drawn using a TQPainter. The drawing capabilities are + implemented by the subclasses TQWidget, TQPixmap, TQPicture and + TQPrinter. + + The default coordinate system of a paint tqdevice has its origin + located at the top-left position. X increases to the right and Y + increases downward. The unit is one pixel. There are several ways + to set up a user-defined coordinate system using the painter, for + example, using TQPainter::setWorldMatrix(). + + Example (draw on a paint tqdevice): + \code + void MyWidget::paintEvent( TQPaintEvent * ) + { + TQPainter p; // our painter + p.begin( this ); // start painting the widget + p.setPen( red ); // red outline + p.setBrush( yellow ); // yellow fill + p.drawEllipse( 10, 20, 100,100 ); // 100x100 ellipse at position (10, 20) + p.end(); // painting done + } + \endcode + + The bit block transfer is an extremely useful operation for + copying pixels from one paint tqdevice to another (or to itself). It + is implemented as the global function bitBlt(). + + Example (scroll widget contents 10 pixels to the right): + \code + bitBlt( myWidget, 10, 0, myWidget ); + \endcode + + \warning TQt requires that a TQApplication object exists before + any paint tqdevices can be created. Paint tqdevices access window + system resources, and these resources are not initialized before + an application object is created. +*/ + + +// +// Some global variables - these are initialized by TQColor::initialize() +// + +Display *TQPaintDevice::x_appdisplay = 0; +int TQPaintDevice::x_appscreen; + +int TQPaintDevice::x_appdepth; +int TQPaintDevice::x_appcells; +TQt::HANDLE TQPaintDevice::x_approotwindow; +TQt::HANDLE TQPaintDevice::x_appcolormap; +bool TQPaintDevice::x_appdefcolormap; +void *TQPaintDevice::x_appvisual; +bool TQPaintDevice::x_appdefvisual; + +// ### in 4.0, remove the above, and use the below +int *TQPaintDevice::x_appdepth_arr; +int *TQPaintDevice::x_appcells_arr; +TQt::HANDLE *TQPaintDevice::x_approotwindow_arr; +TQt::HANDLE *TQPaintDevice::x_appcolormap_arr; +bool *TQPaintDevice::x_appdefcolormap_arr; +void **TQPaintDevice::x_appvisual_arr; +bool *TQPaintDevice::x_appdefvisual_arr; + +/*! + \enum TQPaintDevice::PDevCmd + \internal +*/ + +/*! + Constructs a paint tqdevice with internal flags \a devflags. This + constructor can be invoked only from TQPaintDevice subclasses. +*/ + +TQPaintDevice::TQPaintDevice( uint devflags ) +{ + if ( !tqApp ) { // global constructor +#if defined(TQT_CHECK_STATE) + qFatal( "TQPaintDevice: Must construct a TQApplication before a " + "TQPaintDevice" ); +#endif + return; + } + devFlags = devflags; + painters = 0; + hd = 0; + rendhd = 0; + x11Data = 0; +} + +/*! + Destroys the paint tqdevice and frees window system resources. +*/ + +TQPaintDevice::~TQPaintDevice() +{ +#if defined(TQT_CHECK_STATE) + if ( paintingActive() ) + qWarning( "TQPaintDevice: Cannot destroy paint tqdevice that is being " + "painted" ); +#endif + if ( x11Data && x11Data->deref() ) { + delete x11Data; + x11Data = 0; + } +} + + +/* + \internal + Makes a shallow copy of the X11-specific data of \a fromDevice, if it is not + null. Otherwise this function sets it to null. +*/ + +void TQPaintDevice::copyX11Data( const TQPaintDevice *fromDevice ) +{ + setX11Data( fromDevice ? fromDevice->x11Data : 0 ); +} + +/* + \internal + Makes a deep copy of the X11-specific data of \a fromDevice, if it is not + null. Otherwise this function sets it to null. +*/ + +void TQPaintDevice::cloneX11Data( const TQPaintDevice *fromDevice ) +{ + if ( fromDevice && fromDevice->x11Data ) { + TQPaintDeviceX11Data *d = new TQPaintDeviceX11Data; + *d = *fromDevice->x11Data; + d->count = 0; + setX11Data( d ); + } else { + setX11Data( 0 ); + } +} + +/* + \internal + Makes a shallow copy of the X11-specific data \a d and assigns it to this + class. This function increments the reference code of \a d. +*/ + +void TQPaintDevice::setX11Data( const TQPaintDeviceX11Data* d ) +{ + if ( x11Data && x11Data->deref() ) + delete x11Data; + x11Data = (TQPaintDeviceX11Data*)d; + if ( x11Data ) + x11Data->ref(); +} + + +/* + \internal + If \a def is FALSE, returns a deep copy of the x11Data, or 0 if x11Data is 0. + If \a def is TRUE, makes a TQPaintDeviceX11Data struct filled with the default + values. + + In either case the caller is responsible for deleting the returned + struct. But notice that the struct is a shared class, so other + classes might also have a reference to it. The reference count of + the returned TQPaintDeviceX11Data* is 0. +*/ + +TQPaintDeviceX11Data* TQPaintDevice::getX11Data( bool def ) const +{ + TQPaintDeviceX11Data* res = 0; + if ( def ) { + res = new TQPaintDeviceX11Data; + res->x_display = x11AppDisplay(); + res->x_screen = x11AppScreen(); + res->x_depth = x11AppDepth(); + res->x_cells = x11AppCells(); + res->x_colormap = x11Colormap(); + res->x_defcolormap = x11AppDefaultColormap(); + res->x_visual = x11AppVisual(); + res->x_defvisual = x11AppDefaultVisual(); + res->deref(); + } else if ( x11Data ) { + res = new TQPaintDeviceX11Data; + *res = *x11Data; + res->count = 0; + } + return res; +} + + +/*! + \fn int TQPaintDevice::devType() const + + \internal + + Returns the tqdevice type identifier, which is \c TQInternal::Widget + if the tqdevice is a TQWidget, \c TQInternal::Pixmap if it's a + TQPixmap, \c TQInternal::Printer if it's a TQPrinter, \c + TQInternal::Picture if it's a TQPicture or \c + TQInternal::UndefinedDevice in other cases (which should never + happen). +*/ + +/*! + \fn bool TQPaintDevice::isExtDev() const + + Returns TRUE if the tqdevice is an external paint tqdevice; otherwise + returns FALSE. + + External paint tqdevices cannot be bitBlt()'ed from. TQPicture and + TQPrinter are external paint tqdevices. +*/ + +/*! + Returns the window system handle of the paint tqdevice, for + low-level access. Using this function is not portable. + + The HANDLE type varies with platform; see \c tqpaintdevice.h and + \c tqwindowdefs.h for details. + + \sa x11Display() +*/ +TQt::HANDLE TQPaintDevice::handle() const +{ + return hd; +} + +/*! + Returns the window system handle of the paint tqdevice for XRender + support. Use of this function is not portable. This function will + return 0 if XRender support is not compiled into TQt, if the + XRender extension is not supported on the X11 display, or if the + handle could not be created. +*/ +TQt::HANDLE TQPaintDevice::x11RenderHandle() const +{ +#ifndef TQT_NO_XFTFREETYPE + return rendhd ? XftDrawPicture( (XftDraw *) rendhd ) : 0; +#else + return 0; +#endif // TQT_NO_XFTFREETYPE +} + + +/*! + \fn Display *TQPaintDevice::x11AppDisplay() + + Returns a pointer to the X display global to the application (X11 + only). Using this function is not portable. + + \sa handle() +*/ + +/*! + \fn int TQPaintDevice::x11AppScreen() + + Returns the screen number on the X display global to the + application (X11 only). Using this function is not portable. +*/ + +/*! + \overload + \fn int TQPaintDevice::x11AppDepth() + + Returns the depth for the default screen of the X display global + to the application (X11 only). Using this function is not + portable. + + \sa TQPixmap::defaultDepth() +*/ + +/*! + \fn int TQPaintDevice::x11AppCells() + + Returns the number of entries in the colormap for the default + screen of the X display global to the application (X11 + only). Using this function is not portable. + + \sa x11Colormap() +*/ + +/*! + \fn HANDLE TQPaintDevice::x11AppRootWindow() + + Returns the root window for the default screen of the X display + global to the applicatoin (X11 only). Using this function is not + portable. +*/ + +/*! + \fn HANDLE TQPaintDevice::x11AppColormap() + + Returns the colormap for the default screen of the X display + global to the application (X11 only). Using this function is not + portable. + + \sa x11Cells() +*/ + +/*! + \fn bool TQPaintDevice::x11AppDefaultColormap () + + Returns the default colormap for the default screen of the X + display global to the application (X11 only). Using this function + is not portable. + + \sa x11Cells() +*/ + +/*! + \fn void* TQPaintDevice::x11AppVisual () + + Returns the Visual for the default screen of the X display global + to the application (X11 only). Using this function is not + portable. +*/ + +/*! + \fn bool TQPaintDevice::x11AppDefaultVisual () + + Returns TRUE if the Visual used is the default for the default + screen of the X display global to the application (X11 only); + otherwise returns FALSE. Using this function is not portable. +*/ + +/*! + \fn int TQPaintDevice::x11AppDepth( int screen ) + + Returns the depth for screen \a screen of the X display global to + the application (X11 only). Using this function is not portable. + + \sa TQPixmap::defaultDepth() +*/ + +/*! + \overload + \fn int TQPaintDevice::x11AppCells( int screen ) + + Returns the number of entries in the colormap for screen \a screen + of the X display global to the application (X11 only). Using this + function is not portable. + + \sa x11Colormap() +*/ + +/*! + \overload + \fn HANDLE TQPaintDevice::x11AppRootWindow( int screen ) + + Returns the root window for screen \a screen of the X display + global to the applicatoin (X11 only). Using this function is not + portable. +*/ + +/*! + \overload + \fn HANDLE TQPaintDevice::x11AppColormap( int screen ) + + Returns the colormap for screen \a screen of the X display global + to the application (X11 only). Using this function is not + portable. + + \sa x11Cells() +*/ + +/*! + \overload + \fn bool TQPaintDevice::x11AppDefaultColormap( int screen ) + + Returns the default colormap for screen \a screen of the X display + global to the application (X11 only). Using this function is not + portable. + + \sa x11Cells() +*/ + +/*! + \overload + \fn void* TQPaintDevice::x11AppVisual( int screen ) + + Returns the Visual for screen \a screen of the X display global to + the application (X11 only). Using this function is not portable. +*/ + +/*! + \overload + \fn bool TQPaintDevice::x11AppDefaultVisual( int screen ) + + Returns TRUE if the Visual used is the default for screen + \a screen of the X display global to the application (X11 only); + otherwise returns FALSE. Using this function is not portable. +*/ + + +/*! + \fn Display *TQPaintDevice::x11Display() const + + Returns a pointer to the X display for the paint tqdevice (X11 + only). Using this function is not portable. + + \sa handle() +*/ + +/*! + \fn int TQPaintDevice::x11Screen () const + + Returns the screen number on the X display for the paint tqdevice + (X11 only). Using this function is not portable. +*/ + +/*! + \fn int TQPaintDevice::x11Depth () const + + Returns the depth of the X display for the paint tqdevice (X11 + only). Using this function is not portable. + + \sa TQPixmap::defaultDepth() +*/ + +/*! + \fn int TQPaintDevice::x11Cells () const + + Returns the number of entries in the colormap of the X display for + the paint tqdevice (X11 only). Using this function is not portable. + + \sa x11Colormap() +*/ + +/*! + \fn HANDLE TQPaintDevice::x11Colormap () const + + Returns the colormap of the X display for the paint tqdevice (X11 + only). Using this function is not portable. + + \sa x11Cells() +*/ + +/*! + \fn bool TQPaintDevice::x11DefaultColormap () const + + Returns the default colormap of the X display for the paint tqdevice + (X11 only). Using this function is not portable. + + \sa x11Cells() +*/ + +/*! + \fn void* TQPaintDevice::x11Visual () const + + Returns the Visual of the X display for the paint tqdevice (X11 + only). Using this function is not portable. +*/ + +/*! + \fn bool TQPaintDevice::x11DefaultVisual () const + + Returns the default Visual of the X display for the paint tqdevice + (X11 only). Using this function is not portable. +*/ + +static int *dpisX=0, *dpisY=0; +static void create_dpis() +{ + if ( dpisX ) + return; + + Display *dpy = TQPaintDevice::x11AppDisplay(); + if ( ! dpy ) + return; + + int i, screens = ScreenCount( dpy ); + dpisX = new int[ screens ]; + dpisY = new int[ screens ]; + TQ_CHECK_PTR( dpisX ); + TQ_CHECK_PTR( dpisY ); + for ( i = 0; i < screens; i++ ) { + dpisX[ i ] = (DisplayWidth(dpy,i) * 254 + DisplayWidthMM(dpy,i)*5) + + / (DisplayWidthMM(dpy,i)*10); + dpisY[ i ] = (DisplayHeight(dpy,i) * 254 + DisplayHeightMM(dpy,i)*5) + / (DisplayHeightMM(dpy,i)*10); + } +} + +/*! + Sets the value returned by x11AppDpiX() to \a dpi for screen + \a screen. The default is determined by the display configuration. + Changing this value will alter the scaling of fonts and many other + metrics and is not recommended. Using this function is not + portable. + + \sa x11SetAppDpiY() +*/ +void TQPaintDevice::x11SetAppDpiX(int dpi, int screen) +{ + create_dpis(); + if ( ! dpisX ) + return; + if ( screen < 0 ) + screen = TQPaintDevice::x11AppScreen(); + if ( screen > ScreenCount( TQPaintDevice::x11AppDisplay() ) ) + return; + dpisX[ screen ] = dpi; +} + +/*! + \overload + + Sets the value returned by x11AppDpiX() to \a dpi for the default + screen. The default is determined by the display configuration. + Changing this value will alter the scaling of fonts and many other + metrics and is not recommended. Using this function is not + portable. + +*/ +// ### REMOVE 4.0 +void TQPaintDevice::x11SetAppDpiX( int dpi ) +{ + TQPaintDevice::x11SetAppDpiX( dpi, -1 ); +} + +/*! + Sets the value returned by x11AppDpiY() to \a dpi for screen + \a screen. The default is determined by the display configuration. + Changing this value will alter the scaling of fonts and many other + metrics and is not recommended. Using this function is not + portable. + + \sa x11SetAppDpiX() +*/ +void TQPaintDevice::x11SetAppDpiY(int dpi, int screen) +{ + create_dpis(); + if ( ! dpisY ) + return; + if ( screen < 0 ) + screen = TQPaintDevice::x11AppScreen(); + if ( screen > ScreenCount( TQPaintDevice::x11AppDisplay() ) ) + return; + dpisY[ screen ] = dpi; +} + +/*! + \overload + + Sets the value returned by x11AppDpiY() to \a dpi for the default + screen. The default is determined by the display configuration. + Changing this value will alter the scaling of fonts and many other + metrics and is not recommended. Using this function is not + portable. +*/ +// ### REMOVE 4.0 +void TQPaintDevice::x11SetAppDpiY( int dpi ) +{ + TQPaintDevice::x11SetAppDpiY( dpi, -1 ); +} + +/*! + Returns the horizontal DPI of the X display (X11 only) for screen + \a screen. Using this function is not portable. See + TQPaintDeviceMetrics for portable access to related information. + Using this function is not portable. + + \sa x11AppDpiY(), x11SetAppDpiX(), TQPaintDeviceMetrics::logicalDpiX() +*/ +int TQPaintDevice::x11AppDpiX(int screen) +{ + create_dpis(); + if ( ! dpisX ) + return 0; + if ( screen < 0 ) + screen = TQPaintDevice::x11AppScreen(); + if ( screen > ScreenCount( TQPaintDevice::x11AppDisplay() ) ) + return 0; + return dpisX[ screen ]; +} + +/*! + \overload + + Returns the horizontal DPI of the X display (X11 only) for the + default screen. Using this function is not portable. See + TQPaintDeviceMetrics for portable access to related information. + Using this function is not portable. +*/ +int TQPaintDevice::x11AppDpiX() +{ + return TQPaintDevice::x11AppDpiX( -1 ); +} + +/*! + Returns the vertical DPI of the X11 display (X11 only) for screen + \a screen. Using this function is not portable. See + TQPaintDeviceMetrics for portable access to related information. + Using this function is not portable. + + \sa x11AppDpiX(), x11SetAppDpiY(), TQPaintDeviceMetrics::logicalDpiY() +*/ +int TQPaintDevice::x11AppDpiY( int screen ) +{ + create_dpis(); + if ( ! dpisY ) + return 0; + if ( screen < 0 ) + screen = TQPaintDevice::x11AppScreen(); + if ( screen > ScreenCount( TQPaintDevice::x11AppDisplay() ) ) + return 0; + return dpisY[ screen ]; +} + +/*! + \overload + + Returns the vertical DPI of the X11 display (X11 only) for the + default screen. Using this function is not portable. See + TQPaintDeviceMetrics for portable access to related information. + Using this function is not portable. + + \sa x11AppDpiX(), x11SetAppDpiY(), TQPaintDeviceMetrics::logicalDpiY() +*/ +int TQPaintDevice::x11AppDpiY() +{ + return TQPaintDevice::x11AppDpiY( -1 ); +} + +/*! + \fn bool TQPaintDevice::paintingActive() const + + Returns TRUE if the tqdevice is being painted, i.e. someone has + called TQPainter::begin() but not yet called TQPainter::end() for + this tqdevice; otherwise returns FALSE. + + \sa TQPainter::isActive() +*/ + +/*! + Internal virtual function that interprets drawing commands from + the painter. + + Implemented by subclasses that have no direct support for drawing + graphics (external paint tqdevices, for example, TQPicture). +*/ + +bool TQPaintDevice::cmd( int, TQPainter *, TQPDevCmdParam * ) +{ +#if defined(TQT_CHECK_STATE) + qWarning( "TQPaintDevice::cmd: Device has no command interface" ); +#endif + return FALSE; +} + +/*! + \internal + + Internal virtual function that returns paint tqdevice metrics. + + Please use the TQPaintDeviceMetrics class instead. +*/ + +int TQPaintDevice::metric( int ) const +{ +#if defined(TQT_CHECK_STATE) + qWarning( "TQPaintDevice::metrics: Device has no metric information" ); +#endif + return 0; +} + +/*! + \internal + + Internal virtual function. Reserved for future use. + + Please use the TQFontMetrics class instead. +*/ + +int TQPaintDevice::fontMet( TQFont *, int, const char *, int ) const +{ + return 0; +} + +/*! + \internal + + Internal virtual function. Reserved for future use. + + Please use the TQFontInfo class instead. +*/ + +int TQPaintDevice::fontInf( TQFont *, int ) const +{ + return 0; +} + + +// +// Internal functions for simple GC caching for blt'ing masked pixmaps. +// This cache is used when the pixmap optimization is set to Normal +// and the pixmap size doesn't exceed 128x128. +// + +static bool init_mask_gc = FALSE; +static const int max_mask_gcs = 11; // suitable for hashing + +struct mask_gc { + GC gc; + int mask_no; +}; + +static mask_gc gc_vec[max_mask_gcs]; + + +static void cleanup_mask_gc() +{ + Display *dpy = TQPaintDevice::x11AppDisplay(); + init_mask_gc = FALSE; + for ( int i=0; i<max_mask_gcs; i++ ) { + if ( gc_vec[i].gc ) + XFreeGC( dpy, gc_vec[i].gc ); + } +} + +static GC cache_mask_gc( Display *dpy, Drawable hd, int mask_no, Pixmap tqmask ) +{ + if ( !init_mask_gc ) { // first time initialization + init_mask_gc = TRUE; + qAddPostRoutine( cleanup_mask_gc ); + for ( int i=0; i<max_mask_gcs; i++ ) + gc_vec[i].gc = 0; + } + mask_gc *p = &gc_vec[mask_no % max_mask_gcs]; + if ( !p->gc || p->mask_no != mask_no ) { // not a perfect match + if ( !p->gc ) { // no GC + p->gc = XCreateGC( dpy, hd, 0, 0 ); + XSetGraphicsExposures( dpy, p->gc, False ); + } + XSetClipMask( dpy, p->gc, tqmask ); + p->mask_no = mask_no; + } + return p->gc; +} + + +/*! + \relates TQPaintDevice + + Copies a block of pixels from \a src to \a dst, perhaps merging + each pixel according to the \link TQt::RasterOp raster operation \endlink + \a rop. \a sx, \a sy + is the top-left pixel in \a src (0, 0) by default, \a dx, \a dy is + the top-left position in \a dst and \a sw, \a sh is the size of + the copied block (all of \a src by default). + + The most common values for \a rop are CopyROP and XorROP; the \l + TQt::RasterOp documentation defines all the possible values. + + If \a ignoreMask is FALSE (the default) and \a src is a + masked TQPixmap, the entire blit is masked by \a{src}->tqmask(). + + If \a src, \a dst, \a sw or \a sh is 0, bitBlt() does nothing. If + \a sw or \a sh is negative bitBlt() copies starting at \a sx (and + respectively, \a sy) and ending at the right end (respectively, + bottom) of \a src. + + \a src must be a TQWidget or TQPixmap. You cannot blit from a + TQPrinter, for example. bitBlt() does nothing if you attempt to + blit from an unsupported tqdevice. + + bitBlt() does nothing if \a src has a greater depth than \e dst. + If you need to for example, draw a 24-bit pixmap on an 8-bit + widget, you must use drawPixmap(). +*/ + +void bitBlt( TQPaintDevice *dst, int dx, int dy, + const TQPaintDevice *src, int sx, int sy, int sw, int sh, + TQt::RasterOp rop, bool ignoreMask ) +{ + if ( !src || !dst ) { +#if defined(TQT_CHECK_NULL) + TQ_ASSERT( src != 0 ); + TQ_ASSERT( dst != 0 ); +#endif + return; + } + if ( !src->handle() || src->isExtDev() ) + return; + + TQPaintDevice *pdev = TQPainter::redirect( dst ); + if ( pdev ) + dst = pdev; + + int ts = src->devType(); // from tqdevice type + int td = dst->devType(); // to tqdevice type + Display *dpy = src->x11Display(); + + if ( sw <= 0 ) { // special width + if ( sw < 0 ) + sw = src->metric( TQPaintDeviceMetrics::PdmWidth ) - sx; + else + return; + } + if ( sh <= 0 ) { // special height + if ( sh < 0 ) + sh = src->metric( TQPaintDeviceMetrics::PdmHeight ) - sy; + else + return; + } + + if ( dst->paintingActive() && dst->isExtDev() ) { + TQPixmap *pm; // output to picture/printer + bool tmp_pm = TRUE; + if ( ts == TQInternal::Pixmap ) { + pm = (TQPixmap*)src; + if ( sx != 0 || sy != 0 || + sw != pm->width() || sh != pm->height() || ignoreMask ) { + TQPixmap *tmp = new TQPixmap( sw, sh, pm->depth() ); + bitBlt( tmp, 0, 0, pm, sx, sy, sw, sh, TQt::CopyROP, TRUE ); + if ( pm->tqmask() && !ignoreMask ) { + TQBitmap tqmask( sw, sh ); + bitBlt( &tqmask, 0, 0, pm->tqmask(), sx, sy, sw, sh, + TQt::CopyROP, TRUE ); + tmp->setMask( tqmask ); + } + pm = tmp; + } else { + tmp_pm = FALSE; + } + } else if ( ts == TQInternal::Widget ) {// bitBlt to temp pixmap + pm = new TQPixmap( sw, sh ); + TQ_CHECK_PTR( pm ); + bitBlt( pm, 0, 0, src, sx, sy, sw, sh ); + } else { +#if defined(TQT_CHECK_RANGE) + qWarning( "bitBlt: Cannot bitBlt from tqdevice" ); +#endif + return; + } + TQPDevCmdParam param[3]; + TQRect r(dx, dy, pm->width(), pm->height()); + param[0].rect = &r; + param[1].pixmap = pm; + dst->cmd( TQPaintDevice::PdcDrawPixmap, 0, param ); + if ( tmp_pm ) + delete pm; + return; + } + + switch ( ts ) { + case TQInternal::Widget: + case TQInternal::Pixmap: + case TQInternal::System: // OK, can blt from these + break; + default: +#if defined(TQT_CHECK_RANGE) + qWarning( "bitBlt: Cannot bitBlt from tqdevice type %x", ts ); +#endif + return; + } + switch ( td ) { + case TQInternal::Widget: + case TQInternal::Pixmap: + case TQInternal::System: // OK, can blt to these + break; + default: +#if defined(TQT_CHECK_RANGE) + qWarning( "bitBlt: Cannot bitBlt to tqdevice type %x", td ); +#endif + return; + } + + static const short ropCodes[] = { // ROP translation table + GXcopy, GXor, GXxor, GXandInverted, + GXcopyInverted, GXorInverted, GXequiv, GXand, + GXinvert, GXclear, GXset, GXnoop, + GXandReverse, GXorReverse, GXnand, GXnor + }; + if ( rop > TQt::LastROP ) { +#if defined(TQT_CHECK_RANGE) + qWarning( "bitBlt: Invalid ROP code" ); +#endif + return; + } + + if ( dst->handle() == 0 ) { +#if defined(TQT_CHECK_NULL) + qWarning( "bitBlt: Cannot bitBlt to tqdevice" ); +#endif + return; + } + + bool mono_src; + bool mono_dst; + bool include_inferiors = FALSE; + bool graphics_exposure = FALSE; + TQPixmap *src_pm; + TQBitmap *tqmask; + + if ( ts == TQInternal::Pixmap ) { + src_pm = (TQPixmap*)src; + if ( src_pm->x11Screen() != dst->x11Screen() ) + src_pm->x11SetScreen( dst->x11Screen() ); + mono_src = src_pm->depth() == 1; + tqmask = ignoreMask ? 0 : src_pm->data->tqmask; + } else { + src_pm = 0; + mono_src = FALSE; + tqmask = 0; + include_inferiors = ((TQWidget*)src)->testWFlags(TQt::WPaintUnclipped); + graphics_exposure = td == TQInternal::Widget; + } + if ( td == TQInternal::Pixmap ) { + if ( dst->x11Screen() != src->x11Screen() ) + ((TQPixmap*)dst)->x11SetScreen( src->x11Screen() ); + mono_dst = ((TQPixmap*)dst)->depth() == 1; + ((TQPixmap*)dst)->detach(); // changes shared pixmap + } else { + mono_dst = FALSE; + include_inferiors = include_inferiors || + ((TQWidget*)dst)->testWFlags(TQt::WPaintUnclipped); + } + + if ( mono_dst && !mono_src ) { // dest is 1-bit pixmap, source is not +#if defined(TQT_CHECK_RANGE) + qWarning( "bitBlt: Incompatible destination pixmap" ); +#endif + return; + } + +#ifndef TQT_NO_XRENDER + if (src_pm && !mono_src && src_pm->data->alphapm && !ignoreMask ) { + // use RENDER to do the blit + TQPixmap *alpha = src_pm->data->alphapm; + if (src->x11RenderHandle() && + alpha->x11RenderHandle() && + dst->x11RenderHandle()) { + XRenderPictureAttributes pattr; + ulong pictqmask = 0; + if (include_inferiors) { + pattr.subwindow_mode = IncludeInferiors; + pictqmask |= CPSubwindowMode; + } + if (graphics_exposure) { + pattr.graphics_exposures = TRUE; + pictqmask |= CPGraphicsExposure; + } + if (pictqmask) + XRenderChangePicture(dpy, dst->x11RenderHandle(), pictqmask, &pattr); + XRenderComposite(dpy, PictOpOver, src->x11RenderHandle(), + alpha->x11RenderHandle(), dst->x11RenderHandle(), + sx, sy, sx, sy, dx, dy, sw, sh); + // restore attributes + pattr.subwindow_mode = ClipByChildren; + pattr.graphics_exposures = FALSE; + if (pictqmask) + XRenderChangePicture(dpy, dst->x11RenderHandle(), pictqmask, &pattr); + return; + } + } +#endif + + GC gc; + + if ( tqmask && !mono_src ) { // fast masked blt + bool temp_gc = FALSE; + if ( tqmask->data->maskgc ) { + gc = (GC)tqmask->data->maskgc; // we have a premade tqmask GC + } else { + if ( FALSE && src_pm->optimization() == TQPixmap::NormalOptim ) { // #### cache disabled + // Compete for the global cache + gc = cache_mask_gc( dpy, dst->handle(), + tqmask->data->ser_no, + tqmask->handle() ); + } else { + // Create a new tqmask GC. If BestOptim, we store the tqmask GC + // with the tqmask (not at the pixmap). This way, many pixmaps + // which have a common tqmask will be optimized at no extra cost. + gc = XCreateGC( dpy, dst->handle(), 0, 0 ); + XSetGraphicsExposures( dpy, gc, False ); + XSetClipMask( dpy, gc, tqmask->handle() ); + if ( src_pm->optimization() == TQPixmap::BestOptim ) { + tqmask->data->maskgc = gc; + } else { + temp_gc = TRUE; + } + } + } + XSetClipOrigin( dpy, gc, dx-sx, dy-sy ); + if ( rop != TQt::CopyROP ) // use non-default ROP code + XSetFunction( dpy, gc, ropCodes[rop] ); + if ( include_inferiors ) { + XSetSubwindowMode( dpy, gc, IncludeInferiors ); + XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, + dx, dy ); + XSetSubwindowMode( dpy, gc, ClipByChildren ); + } else { + XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, + dx, dy ); + } + + if ( temp_gc ) // delete temporary GC + XFreeGC( dpy, gc ); + else if ( rop != TQt::CopyROP ) // restore ROP + XSetFunction( dpy, gc, GXcopy ); + return; + } + + gc = qt_xget_temp_gc( dst->x11Screen(), mono_dst ); // get a reusable GC + + if ( rop != TQt::CopyROP ) // use non-default ROP code + XSetFunction( dpy, gc, ropCodes[rop] ); + + if ( mono_src && mono_dst && src == dst ) { // dst and src are the same bitmap + XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, dx, dy ); + } else if ( mono_src ) { // src is bitmap + XGCValues gcvals; + ulong valtqmask = GCBackground | GCForeground | GCFillStyle | + GCStipple | GCTileStipXOrigin | GCTileStipYOrigin; + if ( td == TQInternal::Widget ) { // set GC colors + TQWidget *w = (TQWidget *)dst; + gcvals.background = w->backgroundColor().pixel( dst->x11Screen() ); + gcvals.foreground = w->foregroundColor().pixel( dst->x11Screen() ); + if ( include_inferiors ) { + valtqmask |= GCSubwindowMode; + gcvals.subwindow_mode = IncludeInferiors; + } + } else if ( mono_dst ) { + gcvals.background = 0; + gcvals.foreground = 1; + } else { + gcvals.background = TQt::white.pixel( dst->x11Screen() ); + gcvals.foreground = TQt::black.pixel( dst->x11Screen() ); + } + + gcvals.fill_style = FillOpaqueStippled; + gcvals.stipple = src->handle(); + gcvals.ts_x_origin = dx - sx; + gcvals.ts_y_origin = dy - sy; + + bool cliptqmask = FALSE; + if ( tqmask ) { + if ( ((TQPixmap*)src)->data->selfmask ) { + gcvals.fill_style = FillStippled; + } else { + XSetClipMask( dpy, gc, tqmask->handle() ); + XSetClipOrigin( dpy, gc, dx-sx, dy-sy ); + cliptqmask = TRUE; + } + } + + XChangeGC( dpy, gc, valtqmask, &gcvals ); + XFillRectangle( dpy,dst->handle(), gc, dx, dy, sw, sh ); + + valtqmask = GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; + gcvals.fill_style = FillSolid; + gcvals.ts_x_origin = 0; + gcvals.ts_y_origin = 0; + if ( include_inferiors ) { + valtqmask |= GCSubwindowMode; + gcvals.subwindow_mode = ClipByChildren; + } + XChangeGC( dpy, gc, valtqmask, &gcvals ); + + if ( cliptqmask ) { + XSetClipOrigin( dpy, gc, 0, 0 ); + XSetClipMask( dpy, gc, None ); + } + + } else { // src is pixmap/widget + + if ( graphics_exposure ) // widget to widget + XSetGraphicsExposures( dpy, gc, True ); + if ( include_inferiors ) { + XSetSubwindowMode( dpy, gc, IncludeInferiors ); + XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, + dx, dy ); + XSetSubwindowMode( dpy, gc, ClipByChildren ); + } else { + XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, + dx, dy ); + } + if ( graphics_exposure ) // reset graphics exposure + XSetGraphicsExposures( dpy, gc, False ); + } + + if ( rop != TQt::CopyROP ) // restore ROP + XSetFunction( dpy, gc, GXcopy ); +} + + +/*! + \relates TQPaintDevice + + \overload void bitBlt( TQPaintDevice *dst, const TQPoint &dp, const TQPaintDevice *src, const TQRect &sr, RasterOp rop ) + + Overloaded bitBlt() with the destination point \a dp and source + rectangle \a sr. +*/ + + +/*! + \internal +*/ +// makes it possible to add a setResolution as we have in TQPrinter for all +// painttqdevices without breaking bin compatibility. +void TQPaintDevice::setResolution( int ) +{ +} + +/*!\internal +*/ +int TQPaintDevice::resolution() const +{ + return metric( TQPaintDeviceMetrics::PdmDpiY ); +} + +#endif // USE_QT4
\ No newline at end of file |