📄 qwindowsurface_qws.cpp
字号:
Returns the region that must be repainted. \sa setDirty()*/const QRegion QWSWindowSurface::dirtyRegion() const{ return d_ptr->dirty;}/*! Marks the given \a region as dirty, i.e., altered. \sa dirtyRegion()*/void QWSWindowSurface::setDirty(const QRegion ®ion) const{ if (region.isEmpty()) return; const bool updatePosted = !d_ptr->dirty.isEmpty(); d_ptr->dirty += region & d_ptr->clip; d_ptr->clippedDirty += (region - d_ptr->clip); if (updatePosted) return; QWidget *win = window(); if (win && !d_ptr->dirty.isEmpty()) QApplication::postEvent(win, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);}/*! 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; QWidget *win = window();#ifndef QT_NO_QWS_MANAGER if (win && win->isWindow() && !expose.isEmpty()) { QTLWExtra *topextra = win->d_func()->extra->topextra; QWSManager *manager = topextra->qwsManager; if (manager) { const QRegion r = manager->region().translated( -win->geometry().topLeft()) & expose; if (!r.isEmpty()) manager->d_func()->dirtyRegion(QDecoration::All, QDecoration::Normal, r); } }#endif QRegion dirtyExpose; if (isBuffered()) { dirtyExpose = expose & d_ptr->clippedDirty; d_ptr->clippedDirty -= expose; expose -= dirtyExpose; } else { dirtyExpose = expose; } if (!dirtyExpose.isEmpty()) { setDirty(dirtyExpose); d_ptr->dirty += expose; } else if (!expose.isEmpty()) { // XXX: prevent flush() from resetting dirty and from flushing too much const QRegion oldDirty = d_ptr->dirty; d_ptr->dirty = QRegion(); flush(win, expose, QPoint()); d_ptr->dirty = oldDirty; }}/*! 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::qwsDisplay()->requestRegion(winId(), key(), permanentState(), region); if (needsRepaint) invalidateBuffer();}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; Q_UNUSED(offset); const bool opaque = isWidgetOpaque(win);#ifdef QT_QWS_DISABLE_FLUSHCLIPPING QRegion toFlush = region;#else QRegion toFlush = region & d_ptr->clip;#endif const QRegion stillDirty = (d_ptr->dirty - toFlush); if (!toFlush.isEmpty()) {#ifndef QT_NO_QWS_MANAGER if (win->isWindow()) { QTLWExtra *topextra = win->d_func()->extra->topextra; QWSManager *manager = topextra->qwsManager; if (manager) { QWSManagerPrivate *managerPrivate = manager->d_func(); if (!managerPrivate->dirtyRegions.isEmpty()) { beginPaint(toFlush); managerPrivate->paint(paintDevice(), toFlush); endPaint(toFlush); } } }#endif flushUpdate(widget, toFlush, QPoint(0, 0)); toFlush.translate(win->mapToGlobal(QPoint(0, 0))); win->qwsDisplay()->repaintRegion(winId(), win->windowFlags(), opaque, toFlush); } // XXX: hw: this is not correct when painting outside a paint event. // The dirty region should be moved into QWidgetBackingstore. d_ptr->dirty = QRegion(); setDirty(stillDirty);}/*! 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;}static void scroll(const QImage &img, const QRect &rect, const QPoint &point){ uchar *mem = const_cast<uchar*>(img.bits()); int lineskip = img.bytesPerLine(); int depth = img.depth() >> 3; const QRect r = rect; const QPoint p = rect.topLeft() + point; const uchar *src; uchar *dest; if (r.top() < p.y()) { src = mem + r.bottom() * lineskip + r.left() * depth; dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth; lineskip = -lineskip; } else { src = mem + r.top() * lineskip + r.left() * depth; dest = mem + p.y() * lineskip + p.x() * depth; } const int w = r.width(); int h = r.height(); const int bytes = w * depth; do { ::memmove(dest, src, bytes); dest += lineskip; src += lineskip; } while (--h);}bool QWSMemorySurface::lock(int timeout){ Q_UNUSED(timeout);#ifdef QT_NO_QWS_MULTIPROCESS return true;#else if (!memlock) return true; return memlock->lock(QWSLock::BackingStore);#endif}void QWSMemorySurface::unlock(){#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(){}QPixmap QWSMemorySurface::grabWidget(const QWidget *widget, const QRect &rectangle) const{ QPixmap result; if (widget->window() != window() || img.isNull()) return result; QRect rect = rectangle.isEmpty() ? widget->rect() : (widget->rect() & rectangle); rect.translate(offset(widget)); rect &= QRect(QPoint(), img.size()); if (rect.isEmpty()) return result; QImage subimg(img.scanLine(rect.y()) + rect.x() * img.depth() / 8, rect.width(), rect.height(), img.bytesPerLine(), img.format()); subimg.detach(); //### expensive -- maybe we should have a real SubImage that shares reference count result = QPixmap::fromImage(subimg); return result;}QImage::FormatQWSMemorySurface::preferredImageFormat(const QWidget *widget) const{ const bool opaque = isWidgetOpaque(widget); if (opaque && getScreen(widget)->depth() <= 16) return QImage::Format_RGB16; else return QImage::Format_ARGB32_Premultiplied;}#ifndef QT_NO_QWS_MULTIPROCESSvoid QWSMemorySurface::setLock(int lockId){ if (memlock && memlock->id() == lockId) return; delete memlock; memlock = (lockId == -1 ? 0 : new QWSLock(lockId)); return;}#endif // QT_NO_QWS_MULTIPROCESSbool QWSMemorySurface::isValid() const{ if (img == QImage()) 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;}bool QWSMemorySurface::scroll(const QRegion &area, int dx, int dy){ const QVector<QRect> rects = area.rects(); for (int i = 0; i < rects.size(); ++i) ::scroll(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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -