diff options
Diffstat (limited to 'src/gui/painting/qwindowsurface_qws.cpp')
-rw-r--r-- | src/gui/painting/qwindowsurface_qws.cpp | 1433 |
1 files changed, 0 insertions, 1433 deletions
diff --git a/src/gui/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp deleted file mode 100644 index c52f864b25..0000000000 --- a/src/gui/painting/qwindowsurface_qws.cpp +++ /dev/null @@ -1,1433 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwindowsurface_qws_p.h" -#include <qwidget.h> -#include <qscreen_qws.h> -#include <qwsmanager_qws.h> -#include <qapplication.h> -#include <qwsdisplay_qws.h> -#include <qrgb.h> -#include <qpaintengine.h> -#include <qdesktopwidget.h> -#include <private/qapplication_p.h> -#include <private/qwsdisplay_qws_p.h> -#include <private/qwidget_p.h> -#include <private/qwsmanager_p.h> -#include <private/qwslock_p.h> -#include <private/qbackingstore_p.h> -#include <stdio.h> - -QT_BEGIN_NAMESPACE - -#ifdef Q_BACKINGSTORE_SUBSURFACES - -typedef QMap<int, QWSWindowSurface*> SurfaceMap; -Q_GLOBAL_STATIC(SurfaceMap, winIdToSurfaceMap); - -QWSWindowSurface* qt_findWindowSurface(int winId) -{ - return winIdToSurfaceMap()->value(winId); -} - -static void qt_insertWindowSurface(int winId, QWSWindowSurface *surface) -{ - if (!surface) - winIdToSurfaceMap()->remove(winId); - else - winIdToSurfaceMap()->insert(winId, surface); -} - -#endif // Q_BACKINGSTORE_SUBSURFACES - -inline bool isWidgetOpaque(const QWidget *w) -{ - return w->d_func()->isOpaque && !w->testAttribute(Qt::WA_TranslucentBackground); -} - -static inline QScreen *getScreen(const QWidget *w) -{ - const QList<QScreen*> subScreens = qt_screen->subScreens(); - if (subScreens.isEmpty()) - return qt_screen; - - const int screen = QApplication::desktop()->screenNumber(w); - - return qt_screen->subScreens().at(screen < 0 ? 0 : screen); -} - -static int bytesPerPixel(QImage::Format format) -{ - switch (format) { - case QImage::Format_Invalid: - return 0; -#ifndef QT_NO_DEBUG - case QImage::Format_Mono: - case QImage::Format_MonoLSB: - qFatal("QWSWindowSurface: Invalid backingstore format: %i", - int(format)); -#endif - case QImage::Format_Indexed8: - return 1; - case QImage::Format_RGB32: - case QImage::Format_ARGB32: - case QImage::Format_ARGB32_Premultiplied: - return 4; - case QImage::Format_RGB16: - case QImage::Format_RGB555: - case QImage::Format_RGB444: - case QImage::Format_ARGB4444_Premultiplied: - return 2; - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_ARGB6666_Premultiplied: - case QImage::Format_RGB666: - case QImage::Format_RGB888: - return 3; - default: -#ifndef QT_NO_DEBUG - qFatal("QWSWindowSurface: Invalid backingstore format: %i", - int(format)); -#endif - return 0; - } -} - -static inline int nextMulOf4(int n) -{ - return ((n + 3) & 0xfffffffc); -} - -static inline void setImageMetrics(QImage &img, QWidget *window) { - QScreen *myScreen = getScreen(window); - if (myScreen) { - int dpmx = myScreen->width()*1000 / myScreen->physicalWidth(); - int dpmy = myScreen->height()*1000 / myScreen->physicalHeight(); - img.setDotsPerMeterX(dpmx); - img.setDotsPerMeterY(dpmy); - } -} - -void QWSWindowSurface::invalidateBuffer() -{ - - QWidget *win = window(); - if (win) { - win->d_func()->invalidateBuffer(win->rect()); -#ifndef QT_NO_QWS_MANAGER - QTLWExtra *topextra = win->d_func()->extra->topextra; - QWSManager *manager = topextra->qwsManager; - if (manager) - manager->d_func()->dirtyRegion(QDecoration::All, - QDecoration::Normal); -#endif - } -} - -QWSWindowSurfacePrivate::QWSWindowSurfacePrivate() - : flags(0), -#ifdef QT_QWS_CLIENTBLIT - directId(-1), -#endif - winId(0) -{ -} - -void QWSWindowSurfacePrivate::setWinId(int id) -{ - winId = id; -} - -int QWSWindowSurface::winId() const -{ - // XXX: the widget winId may change during the lifetime of the widget!!! - - const QWidget *win = window(); - if (win && win->isWindow()) - return win->internalWinId(); - -#ifdef Q_BACKINGSTORE_SUBSURFACES - if (!d_ptr->winId) { - QWSWindowSurface *that = const_cast<QWSWindowSurface*>(this); - QWSDisplay *display = QWSDisplay::instance(); - const int id = display->takeId(); - qt_insertWindowSurface(id, that); - that->d_ptr->winId = id; - - if (win) - display->nameRegion(id, win->objectName(), win->windowTitle()); - else - display->nameRegion(id, QString(), QString()); - - display->setAltitude(id, 1, true); // XXX - } -#endif - - return d_ptr->winId; -} - -void QWSWindowSurface::setWinId(int id) -{ - d_ptr->winId = id; -} - -/*! - \class QWSWindowSurface - \since 4.2 - \ingroup qws - \preliminary - \internal - - \brief The QWSWindowSurface class provides the drawing area for top-level - windows in Qt for Embedded Linux. - - Note that this class is only available in Qt for Embedded Linux. - - In \l{Qt for Embedded Linux}, the default behavior is for each client to - render its widgets into memory while the server is responsible for - putting the contents of the memory onto the - screen. QWSWindowSurface is used by the window system to implement - the associated memory allocation. - - When a screen update is required, the server runs through all the - top-level windows that intersect with the region that is about to - be updated, and ensures that the associated clients have updated - their memory buffer. Then the server uses the screen driver to - copy the content of the memory to the screen. To locate the - relevant parts of memory, the driver is provided with the list of - top-level windows that intersect with the given region. Associated - with each of the top-level windows there is a window surface - representing the drawing area of the window. - - When deriving from the QWSWindowSurface class, e.g., when adding - an \l {Adding an Accelerated Graphics Driver to Qt for Embedded Linux} - {accelerated graphics driver}, there are several pure virtual - functions that must be implemented. In addition, QWSWindowSurface - provides several virtual functions that can be reimplemented to - customize the drawing process. - - \tableofcontents - - \section1 Pure Virtual Functions - - There are in fact two window surface instances for each top-level - window; one used by the application when drawing a window, and - another used by the server application to perform window - compositioning. Implement the attach() to create the server-side - representation of the surface. The data() function must be - implemented to provide the required data. - - Implement the key() function to uniquely identify the surface - class, and the isValid() function to determine is a surface - corresponds to a given widget. - - The geometry() function must be implemented to let the window - system determine the area required by the window surface - (QWSWindowSurface also provides a corresponding virtual - setGeometry() function that is called whenever the area necessary - for the top-level window to be drawn, changes). The image() - function is called by the window system during window - compositioning, and must be implemented to return an image of the - top-level window. - - Finally, the paintDevice() function must be implemented to return - the appropriate paint device, and the scroll() function must be - implemented to scroll the given region of the surface the given - number of pixels. - - \section1 Virtual Functions - - When painting onto the surface, the window system will always call - the beginPaint() function before any painting operations are - performed. Likewise the endPaint() function is automatically - called when the painting is done. Reimplement the painterOffset() - function to alter the offset that is applied when drawing. - - The window system uses the flush() function to put a given region - of the widget onto the screen, and the release() function to - deallocate the screen region corresponding to this window surface. - - \section1 Other Members - - QWSWindowSurface provides the window() function returning a - pointer to the top-level window the surface is representing. The - currently visible region of the associated widget can be retrieved - and set using the clipRegion() and setClipRegion() functions, - respectively. - - When the window system performs the window compositioning, it uses - the SurfaceFlag enum describing the surface content. The currently - set surface flags can be retrieved and altered using the - surfaceFlags() and setSurfaceFlags() functions. In addition, - QWSWindowSurface provides the isBuffered(), isOpaque() and - isRegionReserved() convenience functions. - - \sa {Qt for Embedded Linux Architecture#Drawing on Screen}{Qt for - Embedded Linux Architecture} -*/ - -/*! - \enum QWSWindowSurface::SurfaceFlag - - This enum is used to describe the window surface's contents. It - is used by the screen driver to handle region allocation and - composition. - - \value RegionReserved The surface contains a reserved area. Once - allocated, a reserved area can not not be changed by the window - system, i.e., no other widgets can be drawn on top of this. - - \value Buffered - The surface is in a memory area which is not part of a framebuffer. - (A top-level window with QWidget::windowOpacity() other than 1.0 must use - a buffered surface in order to making blending with the background work.) - - \value Opaque - The surface contains only opaque pixels. - - \sa surfaceFlags(), setSurfaceFlags() -*/ - -/*! - \fn bool QWSWindowSurface::isValid() const - \since 4.3 - - Implement this function to return true if the surface is a valid - surface for the given top-level \a window; otherwise return - false. - - \sa window(), key() -*/ - -/*! - \fn QString QWSWindowSurface::key() const - - Implement this function to return a string that uniquely - identifies the class of this surface. - - \sa window(), isValid() -*/ - -/*! - \fn QByteArray QWSWindowSurface::permanentState() const - \since 4.3 - - Implement this function to return the data required for creating a - server-side representation of the surface. - - \sa attach() -*/ - -/*! - \fn void QWSWindowSurface::setPermanentState(const QByteArray &data) - \since 4.3 - - Implement this function to attach a server-side surface instance - to the corresponding client side instance using the given \a - data. Return true if successful; otherwise return false. - - \sa data() -*/ - -/*! - \fn const QImage QWSWindowSurface::image() const - - Implement this function to return an image of the top-level window. - - \sa geometry() -*/ - -/*! - \fn bool QWSWindowSurface::isRegionReserved() const - - Returns true if the QWSWindowSurface::RegionReserved is set; otherwise - returns false. - - \sa surfaceFlags() -*/ - -/*! - \fn bool QWSWindowSurface::isBuffered() const - - Returns true if the QWSWindowSurface::Buffered is set; otherwise returns false. - - \sa surfaceFlags() -*/ - -/*! - \fn bool QWSWindowSurface::isOpaque() const - - Returns true if the QWSWindowSurface::Opaque is set; otherwise - returns false. - - \sa surfaceFlags() -*/ - - -/*! - Constructs an empty surface. -*/ -QWSWindowSurface::QWSWindowSurface() - : QWindowSurface(0), d_ptr(new QWSWindowSurfacePrivate) -{ -} - -/*! - Constructs an empty surface for the given top-level \a widget. -*/ -QWSWindowSurface::QWSWindowSurface(QWidget *widget) - : QWindowSurface(widget), d_ptr(new QWSWindowSurfacePrivate) -{ -} - -QWSWindowSurface::~QWSWindowSurface() -{ -#ifdef Q_BACKINGSTORE_SUBSURFACES - if (d_ptr->winId) - winIdToSurfaceMap()->remove(d_ptr->winId); -#endif - - delete d_ptr; -} - -/*! - Returns the offset to be used when painting. - - \sa paintDevice() -*/ -QPoint QWSWindowSurface::painterOffset() const -{ - const QWidget *w = window(); - if (!w) - return QPoint(); - return w->geometry().topLeft() - w->frameGeometry().topLeft(); -} - -void QWSWindowSurface::beginPaint(const QRegion &) -{ - lock(); -} - -void QWSWindowSurface::endPaint(const QRegion &) -{ - unlock(); -} - -// XXX: documentation!!! -QByteArray QWSWindowSurface::transientState() const -{ - return QByteArray(); -} - -QByteArray QWSWindowSurface::permanentState() const -{ - return QByteArray(); -} - -void QWSWindowSurface::setTransientState(const QByteArray &state) -{ - Q_UNUSED(state); -} - -void QWSWindowSurface::setPermanentState(const QByteArray &state) -{ - Q_UNUSED(state); -} - -bool QWSWindowSurface::lock(int timeout) -{ - Q_UNUSED(timeout); - return true; -} - -void QWSWindowSurface::unlock() -{ -} - -#ifdef QT_QWS_CLIENTBLIT -/*! \internal */ -const QRegion QWSWindowSurface::directRegion() const -{ - return d_ptr->direct; -} - -/*! \internal */ -int QWSWindowSurface::directRegionId() const -{ - return d_ptr->directId; -} - -/*! \internal */ -void QWSWindowSurface::setDirectRegion(const QRegion &r, int id) -{ - d_ptr->direct = r; - d_ptr->directId = id; -} -#endif - -/*! - Returns the region currently visible on the screen. - - \sa setClipRegion() -*/ -const QRegion QWSWindowSurface::clipRegion() const -{ - return d_ptr->clip; -} - -/*! - Sets the region currently visible on the screen to be the given \a - clip region. - - \sa clipRegion() -*/ -void QWSWindowSurface::setClipRegion(const QRegion &clip) -{ - if (clip == d_ptr->clip) - return; - - QRegion expose = (clip - d_ptr->clip); - d_ptr->clip = clip; - - if (expose.isEmpty() || clip.isEmpty()) - return; // No repaint or flush required. - - QWidget *win = window(); - if (!win) - return; - - if (isBuffered()) { - // No repaint required. Flush exposed area via the backing store. - win->d_func()->syncBackingStore(expose); - return; - } - -#ifndef QT_NO_QWS_MANAGER - // Invalidate exposed decoration area. - if (win && win->isWindow()) { - QTLWExtra *topextra = win->d_func()->extra->topextra; - if (QWSManager *manager = topextra->qwsManager) { - QRegion decorationExpose(manager->region()); - decorationExpose.translate(-win->geometry().topLeft()); - decorationExpose &= expose; - if (!decorationExpose.isEmpty()) { - expose -= decorationExpose; - manager->d_func()->dirtyRegion(QDecoration::All, QDecoration::Normal, decorationExpose); - } - } - } -#endif - - // Invalidate exposed widget area. - win->d_func()->invalidateBuffer(expose); -} - -/*! - Returns the surface flags describing the contents of this surface. - - \sa isBuffered(), isOpaque(), isRegionReserved() -*/ -QWSWindowSurface::SurfaceFlags QWSWindowSurface::surfaceFlags() const -{ - return d_ptr->flags; -} - -/*! - Sets the surface flags describing the contents of this surface, to - be the given \a flags. - - \sa surfaceFlags() -*/ -void QWSWindowSurface::setSurfaceFlags(SurfaceFlags flags) -{ - d_ptr->flags = flags; -} - -void QWSWindowSurface::setGeometry(const QRect &rect) -{ - QRegion mask = rect; - - const QWidget *win = window(); - if (win) { -#ifndef QT_NO_QWS_MANAGER - if (win->isWindow()) { - QTLWExtra *topextra = win->d_func()->extra->topextra; - QWSManager *manager = topextra->qwsManager; - - if (manager) { - // The frame geometry is the bounding rect of manager->region, - // which could be too much, so we need to clip. - mask &= (manager->region() + win->geometry()); - } - } -#endif - - const QRegion winMask = win->mask(); - if (!winMask.isEmpty()) - mask &= winMask.translated(win->geometry().topLeft()); - } - - setGeometry(rect, mask); -} - -void QWSWindowSurface::setGeometry(const QRect &rect, const QRegion &mask) -{ - if (rect == geometry()) // XXX: && mask == prevMask - return; - - const bool isResize = rect.size() != geometry().size(); - const bool needsRepaint = isResize || !isBuffered(); - - QWindowSurface::setGeometry(rect); - - const QRegion region = mask & rect; - QWidget *win = window(); - // Only request regions for widgets visible on the screen. - // (Added the !win check for compatibility reasons, because - // there was no "if (win)" check before). - const bool requestQWSRegion = !win || !win->testAttribute(Qt::WA_DontShowOnScreen); - if (requestQWSRegion) - QWidget::qwsDisplay()->requestRegion(winId(), key(), permanentState(), region); - - if (needsRepaint) - invalidateBuffer(); - - if (!requestQWSRegion) { - // We didn't request a region, hence we won't get a QWSRegionEvent::Allocation - // event back from the server so we set the clip directly. We have to - // do this after the invalidateBuffer() call above, as it might trigger a - // backing store sync, resulting in too many update requests. - setClipRegion(region); - } -} - -static inline void flushUpdate(QWidget *widget, const QRegion ®ion, - const QPoint &offset) -{ -#ifdef QT_NO_PAINT_DEBUG - Q_UNUSED(widget); - Q_UNUSED(region); - Q_UNUSED(offset); -#else - static int delay = -1; - - if (delay == -1) - delay = qgetenv("QT_FLUSH_UPDATE").toInt() * 10; - - if (delay == 0) - return; - - static QWSYellowSurface surface(true); - surface.setDelay(delay); - surface.flush(widget, region, offset); -#endif // QT_NO_PAINT_DEBUG -} - -void QWSWindowSurface::flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset) -{ - const QWidget *win = window(); - if (!win) - return; - -#ifndef QT_NO_GRAPHICSVIEW - QWExtra *extra = win->d_func()->extra; - if (extra && extra->proxyWidget) - return; -#endif //QT_NO_GRAPHICSVIEW - - Q_UNUSED(offset); - - const bool opaque = isOpaque(); -#ifdef QT_QWS_DISABLE_FLUSHCLIPPING - QRegion toFlush = region; -#else - QRegion toFlush = region & d_ptr->clip; -#endif - - if (!toFlush.isEmpty()) { - flushUpdate(widget, toFlush, QPoint(0, 0)); - QPoint globalZero = win->mapToGlobal(QPoint(0, 0)); - toFlush.translate(globalZero); - -#ifdef QT_QWS_CLIENTBLIT - bool needRepaint = true; - if (opaque) { - QScreen* widgetScreen = getScreen(widget); - if (widgetScreen->supportsBlitInClients()) { - - QWSDisplay::grab(); - if(directRegion().intersected(toFlush) == toFlush) { - QPoint translate = -globalZero + painterOffset() + geometry().topLeft(); - QRegion flushRegion = toFlush.translated(translate); - widgetScreen->blit(image(), geometry().topLeft(), flushRegion); - widgetScreen->setDirty(toFlush.boundingRect()); - needRepaint = false; - } - QWSDisplay::ungrab(); - } - } - - if(needRepaint) -#endif - win->qwsDisplay()->repaintRegion(winId(), win->windowFlags(), opaque, toFlush); - } -} - -/*! - Move the surface with the given \a offset. - - A subclass may reimplement this function to enable accelerated window move. - It must return true if the move was successful and no repaint is necessary, - false otherwise. - - The default implementation updates the QWindowSurface geometry and - returns true if the surface is buffered; false otherwise. - - This function is called by the window system on the client instance. - - \sa isBuffered() -*/ -bool QWSWindowSurface::move(const QPoint &offset) -{ - QWindowSurface::setGeometry(geometry().translated(offset)); - return isBuffered(); -} - -/*! - Move the surface with the given \a offset. - - The new visible region after the window move is given by \a newClip - in screen coordinates. - - A subclass may reimplement this function to enable accelerated window move. - The returned region indicates the area that still needs to be composed - on the screen. - - The default implementation updates the QWindowSurface geometry and - returns the union of the old and new geometry. - - This function is called by the window system on the server instance. -*/ -QRegion QWSWindowSurface::move(const QPoint &offset, const QRegion &newClip) -{ - const QRegion oldGeometry = geometry(); - QWindowSurface::setGeometry(geometry().translated(offset)); - return oldGeometry + newClip; -} - -void QWSWindowSurface::releaseSurface() -{ -} - -bool QWSMemorySurface::lock(int timeout) -{ - Q_UNUSED(timeout); -#ifndef QT_NO_QWS_MULTIPROCESS - if (memlock && !memlock->lock(QWSLock::BackingStore)) - return false; -#endif -#ifndef QT_NO_THREAD - threadLock.lock(); -#endif - return true; -} - -void QWSMemorySurface::unlock() -{ -#ifndef QT_NO_THREAD - threadLock.unlock(); -#endif -#ifndef QT_NO_QWS_MULTIPROCESS - if (memlock) - memlock->unlock(QWSLock::BackingStore); -#endif -} - -QWSMemorySurface::QWSMemorySurface() - : QWSWindowSurface() -#ifndef QT_NO_QWS_MULTIPROCESS - , memlock(0) -#endif -{ - setSurfaceFlags(Buffered); -} - -QWSMemorySurface::QWSMemorySurface(QWidget *w) - : QWSWindowSurface(w) -{ - SurfaceFlags flags = Buffered; - if (isWidgetOpaque(w)) - flags |= Opaque; - setSurfaceFlags(flags); - -#ifndef QT_NO_QWS_MULTIPROCESS - memlock = QWSDisplay::Data::getClientLock(); -#endif -} - -QWSMemorySurface::~QWSMemorySurface() -{ -} - - -QImage::Format -QWSMemorySurface::preferredImageFormat(const QWidget *widget) const -{ - QScreen *screen = getScreen(widget); - const int depth = screen->depth(); - const bool opaque = isWidgetOpaque(widget); - - if (!opaque) { - if (depth <= 12) - return QImage::Format_ARGB4444_Premultiplied; - else if (depth <= 15) - return QImage::Format_ARGB8555_Premultiplied; - else if (depth <= 16) - return QImage::Format_ARGB8565_Premultiplied; - else if (depth <= 18) - return QImage::Format_ARGB6666_Premultiplied; - else - return QImage::Format_ARGB32_Premultiplied; - } - - QImage::Format format = screen->pixelFormat(); - if (format > QImage::Format_Indexed8) // ### assumes all new image formats supports a QPainter - return format; - - if (depth <= 12) - return QImage::Format_RGB444; - else if (depth <= 15) - return QImage::Format_RGB555; - else if (depth <= 16) - return QImage::Format_RGB16; - else if (depth <= 18) - return QImage::Format_RGB666; - else if (depth <= 24) - return QImage::Format_RGB888; - else - return QImage::Format_ARGB32_Premultiplied; -} - -#ifndef QT_NO_QWS_MULTIPROCESS -void QWSMemorySurface::setLock(int lockId) -{ - if (memlock && memlock->id() == lockId) - return; - delete memlock; - memlock = (lockId == -1 ? 0 : new QWSLock(lockId)); - return; -} -#endif // QT_NO_QWS_MULTIPROCESS - -bool QWSMemorySurface::isValid() const -{ - if (img.isNull()) - return true; - - const QWidget *win = window(); - if (preferredImageFormat(win) != img.format()) - return false; - - if (isOpaque() != isWidgetOpaque(win)) // XXX: use QWidgetPrivate::isOpaque() - return false; - - return true; -} - -// ### copied from qwindowsurface_raster.cpp -- should be cross-platform -void QWSMemorySurface::beginPaint(const QRegion &rgn) -{ - if (!isWidgetOpaque(window())) { - QPainter p(&img); - p.setCompositionMode(QPainter::CompositionMode_Source); - const QVector<QRect> rects = rgn.rects(); - const QColor blank = Qt::transparent; - for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { - QRect r = *it; -#ifdef Q_BACKINGSTORE_SUBSURFACES - r.translate(painterOffset()); -#endif - p.fillRect(r, blank); - } - } - QWSWindowSurface::beginPaint(rgn); -} - -// from qwindowsurface.cpp -extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); - -bool QWSMemorySurface::scroll(const QRegion &area, int dx, int dy) -{ - const QVector<QRect> rects = area.rects(); - for (int i = 0; i < rects.size(); ++i) - qt_scrollRectInImage(img, rects.at(i), QPoint(dx, dy)); - - return true; -} - -QPoint QWSMemorySurface::painterOffset() const -{ - const QWidget *w = window(); - if (!w) - return QPoint(); - - if (w->mask().isEmpty()) - return QWSWindowSurface::painterOffset(); - - const QRegion region = w->mask() - & w->frameGeometry().translated(-w->geometry().topLeft()); - return -region.boundingRect().topLeft(); -} - -QWSLocalMemSurface::QWSLocalMemSurface() - : QWSMemorySurface(), mem(0), memsize(0) -{ -} - -QWSLocalMemSurface::QWSLocalMemSurface(QWidget *w) - : QWSMemorySurface(w), mem(0), memsize(0) -{ -} - -QWSLocalMemSurface::~QWSLocalMemSurface() -{ - if (memsize) - delete[] mem; -} - -void QWSLocalMemSurface::setGeometry(const QRect &rect) -{ - QSize size = rect.size(); - - QWidget *win = window(); - if (win && !win->mask().isEmpty()) { - const QRegion region = win->mask() - & rect.translated(-win->geometry().topLeft()); - size = region.boundingRect().size(); - } - - uchar *deleteLater = 0; - // In case of a Hide event we need to delete the memory after sending the - // event to the server in order to let the server animate the event. - if (size.isEmpty()) { - deleteLater = mem; - mem = 0; - } - - if (img.size() != size) { - delete[] mem; - if (size.isEmpty()) { - mem = 0; - img = QImage(); - } else { - const QImage::Format format = preferredImageFormat(win); - const int bpl = nextMulOf4(bytesPerPixel(format) * size.width()); - const int memsize = bpl * size.height(); - mem = new uchar[memsize]; - img = QImage(mem, size.width(), size.height(), bpl, format); - setImageMetrics(img, win); - } - } - - QWSWindowSurface::setGeometry(rect); - delete[] deleteLater; -} - -QByteArray QWSLocalMemSurface::permanentState() const -{ - QByteArray array; - array.resize(sizeof(uchar*) + 3 * sizeof(int) + - sizeof(SurfaceFlags)); - - char *ptr = array.data(); - - *reinterpret_cast<uchar**>(ptr) = mem; - ptr += sizeof(uchar*); - - reinterpret_cast<int*>(ptr)[0] = img.width(); - reinterpret_cast<int*>(ptr)[1] = img.height(); - ptr += 2 * sizeof(int); - - *reinterpret_cast<int *>(ptr) = img.format(); - ptr += sizeof(int); - - *reinterpret_cast<SurfaceFlags*>(ptr) = surfaceFlags(); - - return array; -} - -void QWSLocalMemSurface::setPermanentState(const QByteArray &data) -{ - int width; - int height; - QImage::Format format; - SurfaceFlags flags; - - const char *ptr = data.constData(); - - mem = *reinterpret_cast<uchar* const*>(ptr); - ptr += sizeof(uchar*); - - width = reinterpret_cast<const int*>(ptr)[0]; - height = reinterpret_cast<const int*>(ptr)[1]; - ptr += 2 * sizeof(int); - - format = QImage::Format(*reinterpret_cast<const int*>(ptr)); - ptr += sizeof(int); - - flags = *reinterpret_cast<const SurfaceFlags*>(ptr); - - const int bpl = nextMulOf4(bytesPerPixel(format) * width); - QWSMemorySurface::img = QImage(mem, width, height, bpl, format); - setSurfaceFlags(flags); -} - -void QWSLocalMemSurface::releaseSurface() -{ - mem = 0; - img = QImage(); -} - -#ifndef QT_NO_QWS_MULTIPROCESS - -QWSSharedMemSurface::QWSSharedMemSurface() - : QWSMemorySurface() -{ -} - -QWSSharedMemSurface::QWSSharedMemSurface(QWidget *widget) - : QWSMemorySurface(widget) -{ -} - -QWSSharedMemSurface::~QWSSharedMemSurface() -{ - // mem.detach() is done automatically by ~QSharedMemory -} - -bool QWSSharedMemSurface::setMemory(int memId) -{ - if (mem.id() == memId) - return true; - - mem.detach(); - if (!mem.attach(memId)) { - perror("QWSSharedMemSurface: attaching to shared memory"); - qCritical("QWSSharedMemSurface: Error attaching to" - " shared memory 0x%x", memId); - return false; - } - - return true; -} - -#ifdef QT_QWS_CLIENTBLIT -void QWSSharedMemSurface::setDirectRegion(const QRegion &r, int id) -{ - QWSMemorySurface::setDirectRegion(r, id); - if(mem.address()) - *(uint *)mem.address() = id; -} - -const QRegion QWSSharedMemSurface::directRegion() const -{ - QWSSharedMemory *cmem = const_cast<QWSSharedMemory *>(&mem); - if (cmem->address() && ((int*)cmem->address())[0] == directRegionId()) - return QWSMemorySurface::directRegion(); - else - return QRegion(); -} -#endif - -void QWSSharedMemSurface::setPermanentState(const QByteArray &data) -{ - int memId; - int width; - int height; - int lockId; - QImage::Format format; - SurfaceFlags flags; - - const int *ptr = reinterpret_cast<const int*>(data.constData()); - - memId = ptr[0]; - width = ptr[1]; - height = ptr[2]; - lockId = ptr[3]; - format = QImage::Format(ptr[4]); - flags = SurfaceFlags(ptr[5]); - - setSurfaceFlags(flags); - setMemory(memId); - setLock(lockId); - -#ifdef QT_QWS_CLIENTBLIT - uchar *base = static_cast<uchar*>(mem.address()) + sizeof(uint); -#else - uchar *base = static_cast<uchar*>(mem.address()); -#endif - const int bpl = nextMulOf4(bytesPerPixel(format) * width); - QWSMemorySurface::img = QImage(base, width, height, bpl, format); -} - -void QWSSharedMemSurface::setGeometry(const QRect &rect) -{ - const QSize size = rect.size(); - if (img.size() != size) { - if (size.isEmpty()) { - mem.detach(); - img = QImage(); - } else { - mem.detach(); - - QWidget *win = window(); - const QImage::Format format = preferredImageFormat(win); - const int bpl = nextMulOf4(bytesPerPixel(format) * size.width()); -#ifdef QT_QWS_CLIENTBLIT - const int imagesize = bpl * size.height() + sizeof(uint); -#else - const int imagesize = bpl * size.height(); -#endif - if (!mem.create(imagesize)) { - perror("QWSSharedMemSurface::setGeometry allocating shared memory"); - qFatal("Error creating shared memory of size %d", imagesize); - } -#ifdef QT_QWS_CLIENTBLIT - *((uint *)mem.address()) = 0; - uchar *base = static_cast<uchar*>(mem.address()) + sizeof(uint); -#else - uchar *base = static_cast<uchar*>(mem.address()); -#endif - img = QImage(base, size.width(), size.height(), bpl, format); - setImageMetrics(img, win); - } - } - - QWSWindowSurface::setGeometry(rect); -} - -QByteArray QWSSharedMemSurface::permanentState() const -{ - QByteArray array; - array.resize(6 * sizeof(int)); - - int *ptr = reinterpret_cast<int*>(array.data()); - - ptr[0] = mem.id(); - ptr[1] = img.width(); - ptr[2] = img.height(); - ptr[3] = (memlock ? memlock->id() : -1); - ptr[4] = int(img.format()); - ptr[5] = int(surfaceFlags()); - - return array; -} - -void QWSSharedMemSurface::releaseSurface() -{ - mem.detach(); - img = QImage(); -} - -#endif // QT_NO_QWS_MULTIPROCESS - -#ifndef QT_NO_PAINTONSCREEN - -QWSOnScreenSurface::QWSOnScreenSurface(QWidget *w) - : QWSMemorySurface(w) -{ - attachToScreen(getScreen(w)); - setSurfaceFlags(Opaque); -} - -QWSOnScreenSurface::QWSOnScreenSurface() - : QWSMemorySurface() -{ - setSurfaceFlags(Opaque); -} - -void QWSOnScreenSurface::attachToScreen(const QScreen *s) -{ - screen = s; - uchar *base = screen->base(); - QImage::Format format = screen->pixelFormat(); - - if (format == QImage::Format_Invalid || format == QImage::Format_Indexed8) { - //### currently we have no paint engine for indexed image formats - qFatal("QWSOnScreenSurface::attachToScreen(): screen depth %d " - "not implemented", screen->depth()); - return; - } - QWSMemorySurface::img = QImage(base, screen->width(), screen->height(), - screen->linestep(), format ); -} - -QWSOnScreenSurface::~QWSOnScreenSurface() -{ -} - -QPoint QWSOnScreenSurface::painterOffset() const -{ - return geometry().topLeft() + QWSWindowSurface::painterOffset(); -} - -bool QWSOnScreenSurface::isValid() const -{ - const QWidget *win = window(); - if (screen != getScreen(win)) - return false; - if (img.isNull()) - return false; - return QScreen::isWidgetPaintOnScreen(win); -} - -QByteArray QWSOnScreenSurface::permanentState() const -{ - QByteArray array; - array.resize(sizeof(int)); - int *ptr = reinterpret_cast<int*>(array.data()); - ptr[0] = QApplication::desktop()->screenNumber(window()); - return array; -} - -void QWSOnScreenSurface::setPermanentState(const QByteArray &data) -{ - const int *ptr = reinterpret_cast<const int*>(data.constData()); - const int screenNo = ptr[0]; - - QScreen *screen = qt_screen; - if (screenNo > 0) - screen = qt_screen->subScreens().at(screenNo); - attachToScreen(screen); -} - -#endif // QT_NO_PAINTONSCREEN - -#ifndef QT_NO_PAINT_DEBUG - -QWSYellowSurface::QWSYellowSurface(bool isClient) - : QWSWindowSurface(), delay(10) -{ - if (isClient) { - setWinId(QWidget::qwsDisplay()->takeId()); - QWidget::qwsDisplay()->nameRegion(winId(), - QLatin1String("Debug flush paint"), - QLatin1String("Silly yellow thing")); - QWidget::qwsDisplay()->setAltitude(winId(), 1, true); - } - setSurfaceFlags(Buffered); -} - -QWSYellowSurface::~QWSYellowSurface() -{ -} - -QByteArray QWSYellowSurface::permanentState() const -{ - QByteArray array; - array.resize(2 * sizeof(int)); - - int *ptr = reinterpret_cast<int*>(array.data()); - ptr[0] = surfaceSize.width(); - ptr[1] = surfaceSize.height(); - - return array; -} - -void QWSYellowSurface::setPermanentState(const QByteArray &data) -{ - const int *ptr = reinterpret_cast<const int*>(data.constData()); - - const int width = ptr[0]; - const int height = ptr[1]; - - img = QImage(width, height, QImage::Format_ARGB32); - img.fill(qRgba(255,255,31,127)); -} - -void QWSYellowSurface::flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset) -{ - Q_UNUSED(offset); - - QWSDisplay *display = QWidget::qwsDisplay(); - QRegion rgn = region; - - if (widget) - rgn.translate(widget->mapToGlobal(QPoint(0, 0))); - - surfaceSize = region.boundingRect().size(); - - const int id = winId(); - display->requestRegion(id, key(), permanentState(), rgn); - display->setAltitude(id, 1, true); - display->repaintRegion(id, 0, false, rgn); - - ::usleep(500 * delay); - display->requestRegion(id, key(), permanentState(), QRegion()); - ::usleep(500 * delay); -} - -#endif // QT_NO_PAINT_DEBUG - -#ifndef QT_NO_DIRECTPAINTER - -static inline QScreen *getPrimaryScreen() -{ - QScreen *screen = QScreen::instance(); - if (!screen->base()) { - QList<QScreen*> subScreens = screen->subScreens(); - if (subScreens.size() < 1) - return 0; - screen = subScreens.at(0); - } - return screen; -} - -QWSDirectPainterSurface::QWSDirectPainterSurface(bool isClient, - QDirectPainter::SurfaceFlag flags) - : QWSWindowSurface(), flushingRegionEvents(false), doLocking(false) -{ - setSurfaceFlags(Opaque); - synchronous = (flags == QDirectPainter::ReservedSynchronous); - - if (isClient) { - setWinId(QWidget::qwsDisplay()->takeId()); - QWidget::qwsDisplay()->nameRegion(winId(), - QLatin1String("QDirectPainter reserved space"), - QLatin1String("reserved")); - } else { - setWinId(0); - } - _screen = QScreen::instance(); - if (!_screen->base()) { - QList<QScreen*> subScreens = _screen->subScreens(); - if (subScreens.size() < 1) - _screen = 0; - else - _screen = subScreens.at(0); - } -} - -QWSDirectPainterSurface::~QWSDirectPainterSurface() -{ - if (winId() && QWSDisplay::instance()) // make sure not in QApplication destructor - QWidget::qwsDisplay()->destroyRegion(winId()); -} - -void QWSDirectPainterSurface::setRegion(const QRegion ®ion) -{ - const int id = winId(); - QWidget::qwsDisplay()->requestRegion(id, key(), permanentState(), region); -#ifndef QT_NO_QWS_MULTIPROCESS - if (synchronous) - QWSDisplay::instance()->d->waitForRegionAck(id); -#endif -} - -void QWSDirectPainterSurface::flush(QWidget *, const QRegion &r, const QPoint &) -{ - QWSDisplay::instance()->repaintRegion(winId(), 0, true, r); -} - -QByteArray QWSDirectPainterSurface::permanentState() const -{ - QByteArray res; - if (isRegionReserved()) - res.append( 'r'); - return res; -} - -void QWSDirectPainterSurface::setPermanentState(const QByteArray &ba) -{ - if (ba.size() > 0 && ba.at(0) == 'r') - setReserved(); - setSurfaceFlags(surfaceFlags() | Opaque); -} - -void QWSDirectPainterSurface::beginPaint(const QRegion ®ion) -{ - QWSWindowSurface::beginPaint(region); -#ifndef QT_NO_QWS_MULTIPROCESS - if (!synchronous) { - flushingRegionEvents = true; - QWSDisplay::instance()->d->waitForRegionEvents(winId(), doLocking); - flushingRegionEvents = false; - } -#endif -} - -bool QWSDirectPainterSurface::hasPendingRegionEvents() const -{ -#ifndef QT_NO_QWS_MULTIPROCESS - if (synchronous) - return false; - - return QWSDisplay::instance()->d->hasPendingRegionEvents(); -#else - return false; -#endif -} - -bool QWSDirectPainterSurface::lock(int timeout) -{ -#ifndef QT_NO_THREAD - threadLock.lock(); -#endif - Q_UNUSED(timeout); - if (doLocking) - QWSDisplay::grab(true); - return true; -} - -void QWSDirectPainterSurface::unlock() -{ - if (doLocking) - QWSDisplay::ungrab(); -#ifndef QT_NO_THREAD - threadLock.unlock(); -#endif -} - -#endif // QT_NO_DIRECTPAINTER - -QT_END_NAMESPACE |