From e9704a297f788bb79b2a89e9b16214443931af5d Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 25 Nov 2009 14:47:32 +0000 Subject: Symbian control invokes slots before and after native draw ops Direct Screen Access (DSA) allows a client to request notification from the window server when drawing is performed by other threads, into a specified region of the screen. This allows DSA rendering - for example video - to be suspended when notifications are drawn, preventing the video content from overwriting the notification. If the drawing originates from the same thread as that which holds the DSA session, DSA must be suspended while drawing takes place. This change allows a widget to request notification when native drawing is about to be performed by QSymbianControl::Draw. Task-number: QTBUG-5467 Reviewed-by: Jason Barron --- src/gui/kernel/qapplication_s60.cpp | 19 +++++++++++++++++++ src/gui/kernel/qwidget_p.h | 9 +++++++++ src/gui/kernel/qwidget_s60.cpp | 1 + 3 files changed, 29 insertions(+) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index ae7b494..d1471eb 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -812,6 +812,12 @@ void QSymbianControl::Draw(const TRect& controlRect) const if (!engine) return; + const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents; + if (sendNativePaintEvents) { + const QRect r = qt_TRect2QRect(controlRect); + QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r)); + } + // Map source rectangle into coordinates of the backing store. const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY); const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase); @@ -851,6 +857,19 @@ void QSymbianControl::Draw(const TRect& controlRect) const } else { surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint()); } + + if (sendNativePaintEvents) { + const QRect r = qt_TRect2QRect(controlRect); + // The draw ops aren't actually sent to WSERV until the graphics + // context is deactivated, which happens in the function calling + // this one. We therefore delay the delivery of endNativePaintEvent, + // to ensure that drawing has completed by the time the widget + // receives the event. Note that, if the widget needs to ensure + // that the draw ops have actually been executed into the output + // framebuffer, a call to RWsSession::Flush is required in the + // endNativePaintEvent implementation. + QMetaObject::invokeMethod(qwidget, "endNativePaintEvent", Qt::QueuedConnection, Q_ARG(QRect, r)); + } } void QSymbianControl::SizeChanged() diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 025d703..04cf4bb 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -257,6 +257,15 @@ struct QWExtra { NativePaintMode nativePaintMode : 2; + /** + * If this bit is set, each native widget receives the signals from the + * Symbian control immediately before and immediately after draw ops are + * sent to the window server for this control: + * void beginNativePaintEvent(const QRect &paintRect); + * void endNativePaintEvent(const QRect &paintRect); + */ + uint receiveNativePaintEvents : 1; + #endif }; diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index d7d76df..37614c7 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -882,6 +882,7 @@ void QWidgetPrivate::createSysExtra() { extra->activated = 0; extra->nativePaintMode = QWExtra::Default; + extra->receiveNativePaintEvents = 0; } void QWidgetPrivate::deleteSysExtra() -- cgit v0.12