From aa077a8bd3ee3a134629ef6ac2367b7f11593724 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 4 May 2009 10:44:53 +0200 Subject: Do not crash when passing wrong indexes to QSortFilterProxyModel::indexFomSource and *ToSource Show a warning instead Task-number: 252507 Reviewed-by: Marius Bugge Monsen --- src/gui/itemviews/qsortfilterproxymodel.cpp | 9 +++++++++ .../tst_qsortfilterproxymodel.cpp | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index 91431c4..43feda8 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -144,6 +144,7 @@ public: const QModelIndex &proxy_index) const { Q_ASSERT(proxy_index.isValid()); + Q_ASSERT(proxy_index.model() == q_func()); const void *p = proxy_index.internalPointer(); Q_ASSERT(p); QMap::const_iterator it = @@ -311,6 +312,10 @@ QModelIndex QSortFilterProxyModelPrivate::proxy_to_source(const QModelIndex &pro { if (!proxy_index.isValid()) return QModelIndex(); // for now; we may want to be able to set a root index later + if (proxy_index.model() != q_func()) { + qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapToSource"; + return QModelIndex(); + } IndexMap::const_iterator it = index_to_iterator(proxy_index); Mapping *m = it.value(); if ((proxy_index.row() >= m->source_rows.size()) || (proxy_index.column() >= m->source_columns.size())) @@ -324,6 +329,10 @@ QModelIndex QSortFilterProxyModelPrivate::source_to_proxy(const QModelIndex &sou { if (!source_index.isValid()) return QModelIndex(); // for now; we may want to be able to set a root index later + if (source_index.model() != model) { + qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapFromSource"; + return QModelIndex(); + } QModelIndex source_parent = source_index.parent(); IndexMap::const_iterator it = create_mapping(source_parent); Mapping *m = it.value(); diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 18aa5fc..bd66fdf 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -133,6 +133,7 @@ private slots: void task248868_dynamicSorting(); void task250023_fetchMore(); void task251296_hiddenChildren(); + void task252507_mapFromToSource(); protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); @@ -2612,6 +2613,7 @@ class QtTestModel: public QAbstractItemModel return fetched.contains(parent) ? rows : 0; } int columnCount(const QModelIndex& parent = QModelIndex()) const { + Q_UNUSED(parent); return cols; } @@ -2717,6 +2719,22 @@ void tst_QSortFilterProxyModel::task251296_hiddenChildren() QCOMPARE(proxy.data(indexC).toString(), QString::fromLatin1("C VISIBLE")); } +void tst_QSortFilterProxyModel::task252507_mapFromToSource() +{ + QtTestModel source(10,10); + source.fetchMore(QModelIndex()); + QSortFilterProxyModel proxy; + proxy.setSourceModel(&source); + QCOMPARE(proxy.mapFromSource(source.index(5, 4)), proxy.index(5, 4)); + QCOMPARE(proxy.mapToSource(proxy.index(3, 2)), source.index(3, 2)); + QCOMPARE(proxy.mapFromSource(QModelIndex()), QModelIndex()); + QCOMPARE(proxy.mapToSource(QModelIndex()), QModelIndex()); + + QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapToSource "); + QCOMPARE(proxy.mapToSource(source.index(2, 3)), QModelIndex()); + QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapFromSource "); + QCOMPARE(proxy.mapFromSource(proxy.index(6, 2)), QModelIndex()); +} QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" -- cgit v0.12 From e223a450ce57a7dc627e0eac14cea019f99fe601 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Mon, 4 May 2009 13:13:51 +0200 Subject: Added comment to clearify the use of indexes. Added a comment about the use of negative indexes. Task-number: 249344 Rev-by: Marius Storm-Olsen --- src/corelib/tools/qlistdata.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/corelib/tools/qlistdata.cpp b/src/corelib/tools/qlistdata.cpp index d7c39a7..d40b6b6 100644 --- a/src/corelib/tools/qlistdata.cpp +++ b/src/corelib/tools/qlistdata.cpp @@ -764,6 +764,10 @@ void **QListData::erase(void **xi) This function requires the value type to have an implementation of \c operator==(). + Note that QList uses 0-based indexes, just like C++ arrays. Negative + indexes are not supported with the exception of the value mentioned + above. + \sa lastIndexOf(), contains() */ @@ -780,6 +784,10 @@ void **QListData::erase(void **xi) This function requires the value type to have an implementation of \c operator==(). + Note that QList uses 0-based indexes, just like C++ arrays. Negative + indexes are not supported with the exception of the value mentioned + above. + \sa indexOf() */ -- cgit v0.12 From f51ce7c1b349b31f61df48786148c8b3525e2a2c Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Mon, 4 May 2009 13:30:07 +0200 Subject: Doc - Clarifying how to override a Widget's size hint in the Getting to Know Qt Designer document. Task-number: 165435 Reviewed-by: Friedemann Kleint --- doc/src/designer-manual.qdoc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index e10a5be..03b74e6 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -344,10 +344,14 @@ of a QLineEdit or the width and height of item view widgets. This is where the widget size constraints -- \l{QWidget::minimumSize()}{minimumSize} and \l{QWidget::maximumSize()}{maximumSize} constraints come into play. These - are properties you can set in the property editor. Alternatively, to use - the current size as a size constraint value, choose one of the - \gui{Size Constraint} options from the widget's context menu. The layout - will then ensure that those constraints are met. + are properties you can set in the property editor. For example, to override + the default \l{QWidget::}{sizeHint()}, simply set + \l{QWidget::minimumSize()}{minimumSize} and \l{QWidget::maximumSize()} + {maximumSize} to the same value. Alternatively, to use the current size as + a size constraint value, choose one of the \gui{Size Constraint} options + from the widget's context menu. The layout will then ensure that those + constraints are met. To control the size of your widgets via code, you can + reimplement \l{QWidget::}{sizeHint()} in your code. The screenshot below shows the breakdown of a basic user interface designed using a grid. The coordinates on the screenshot show the position of each -- cgit v0.12 From 80aef133fd2c8da3cc1a6607c1c044eaca768169 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 26 Apr 2009 17:21:24 +0200 Subject: Greatly reduced the complexity of the boilerplate function. I found out that all I needed to load the proper libraries was to add a string to the ".interp" section of the ELF executable containing the path to ld.so Reviewed-By: Marius Storm-Olsen --- src/corelib/global/qlibraryinfo.cpp | 107 ++++++------------------------------ 1 file changed, 17 insertions(+), 90 deletions(-) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index ada08c7..29e356e 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -485,100 +485,27 @@ QT_END_NAMESPACE #if defined(Q_CC_GNU) && defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) && !defined(QT_BOOTSTRAPPED) -# include -# include - -static const char boilerplate[] = - "This is the QtCore library version " QT_VERSION_STR "\n" - "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).\n" - "Contact: Qt Software Information (qt-info@nokia.com)\n" - "\n" - "Build key: " QT_BUILD_KEY; - -extern "C" { -void qt_core_init_boilerplate() __attribute__((noreturn)); -} +# include +# include -# if defined(QT_ARCH_I386) -#define sysinit() (void)0 -#define syswrite(msg, len) \ - ({ int res; \ - asm volatile ("movl %%ebx, %%edi\n" \ - "movl $1, %%ebx\n" \ - "int $0x80\n" \ - "movl %%edi, %%ebx\n" \ - : "=a" (res) : "0" (SYS_write), "c" (msg), "d" (len) : "edi"); res; }) -#define sysexit(c) \ - asm ("xor %%ebx, %%ebx\n" \ - "int $0x80\n" \ - : : "a" (SYS_exit)); _exit(c) - -# elif defined(QT_ARCH_X86_64) -#define sysinit() (void)0 -#define syswrite(msg, len) \ - ({ int res; \ - asm volatile ("syscall\n" \ - : "=a" (res) : "0" (SYS_write), "D" (1), "S" (msg), "d" (len) : "rcx"); res; }) -#define sysexit(c) \ - asm ("syscall\n" \ - : : "a" (SYS_exit), "D" (0)); _exit(c) - -# elif defined(QT_ARCH_IA64) -#define sysinit() \ - asm volatile ("{.mlx\n" \ - " nop.m 0\n" \ - " movl r2 = @pcrel(boilerplate);;" \ - "}\n" \ - "{.mii\n" \ - " mov r10 = @ltoffx(boilerplate)\n" \ - " mov r1 = ip\n" \ - " adds r2 = -16, r2\n;;\n" \ - "}\n" \ - " add r1 = r2, r1;;\n" \ - " sub r1 = r1, r10;;\n" \ - : : : "r2", "r10") -#define syswrite(msg, len) \ - ({ const char *_msg = msg; \ - asm ("mov out0=%1\n" \ - "mov out1=%2\n" \ - "mov out2=%3\n" \ - ";;\n" \ - "mov r15=%0\n" \ - "break 0x100000;;\n" \ - : : "I" (SYS_write), "I" (1), "r" (_msg), "r" (len)); }) -#define sysexit(c) \ - asm ("mov out0=%1\n" \ - ";;\n" \ - "mov r15=%0\n" \ - "break 0x100000;;\n" \ - : : "I" (SYS_exit), "O" (0)); write(1, 0, 0); _exit(c) -# else -#define sysinit() (void)0 -#define syswrite(msg, len) (msg); (len) -#define sysexit(c) __builtin_exit(c) -# endif - -#define sysputs(msg) syswrite(msg, -1 + sizeof(msg)) -#define sysendl() syswrite("\n", 1) -#define print_qt_configure(_which) \ - ({const char *which = _which; \ - which += 12; \ - int len = 0; \ - while (which[len]) ++len; \ - syswrite(which, len); }) +extern const char qt_core_interpreter[] __attribute__((section(".interp"))) + = "/lib/ld-linux.so.2"; +extern "C" void qt_core_init_boilerplate() { - sysinit(); - sysputs(boilerplate); - sysputs("\nInstallation prefix: "); - print_qt_configure(qt_configure_prefix_path_str); - sysputs("\nLibrary path: "); - print_qt_configure(qt_configure_libraries_path_str); - sysputs("\nInclude path: "); - print_qt_configure(qt_configure_headers_path_str); - sysendl(); - sysexit(0); + printf("This is the QtCore library version " QT_VERSION_STR "\n" + "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).\n" + "Contact: Qt Software Information (qt-info@nokia.com)\n" + "\n" + "Build key: " QT_BUILD_KEY "\n" + "Installation prefix: %s\n" + "Library path: %s\n" + "Include path: %s\n", + qt_configure_prefix_path_str + 12, + qt_configure_libraries_path_str + 12, + qt_configure_headers_path_str + 12); + exit(0); } #endif -- cgit v0.12 From 237b4b8c8e9b5184578b4776c5f1f554c0d8efb5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 4 May 2009 11:48:46 +0200 Subject: Fixed D-Bus socket write notifications, broken since d47c05b1 Shame on me: copy/paste from socketRead to socketWrite, I didn't change the DBUS_WATCH_READABLE to DBUS_WATCH_WRITABLE. Reviewed-by: Trust Me --- src/dbus/qdbusintegrator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 8c701f5..2c27381 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1102,7 +1102,7 @@ void QDBusConnectionPrivate::socketWrite(int fd) } for (int i = 0; i < pendingWatches.size(); ++i) - if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_READABLE)) + if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_WRITABLE)) qDebug("OUT OF MEM"); } -- cgit v0.12 From ea91eb38d81e37bd12d6abc2604f025ac1d254ce Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 4 May 2009 13:54:47 +0200 Subject: Ensure that we send the Apple Events even when Cocoa isn't ready. In general, Cocoa handles the the Apple Events for us. However, this is time between creating the NSApplication and Cocoa has set everything up, usually after the event loop is running. This means that until that time, the events are dropped on the floor :-/. The workaround is to use the same handler that we use for Carbon, but to only have it enabled for until Cocoa is ready to handle things. This will result in not stepping on the toes when used in a plugin (if it does, we can conditionalize it). Task-number: 252795 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qapplication_mac.mm | 32 ++++++++++++++++--------- src/gui/kernel/qcocoaapplicationdelegate_mac.mm | 2 ++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 5f8c572..69302ec 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -194,8 +194,8 @@ static bool appNoGrab = false; // mouse/keyboard grabbing #ifndef QT_MAC_USE_COCOA static EventHandlerRef app_proc_handler = 0; static EventHandlerUPP app_proc_handlerUPP = 0; -static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL; #endif +static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL; static EventHandlerRef tablet_proximity_handler = 0; static EventHandlerUPP tablet_proximity_UPP = 0; bool QApplicationPrivate::native_modal_dialog_active; @@ -951,7 +951,6 @@ void qt_mac_event_release(QWidget *w) } } -#ifndef QT_MAC_USE_COCOA struct QMacAppleEventTypeSpec { AEEventClass mac_class; AEEventID mac_id; @@ -959,6 +958,7 @@ struct QMacAppleEventTypeSpec { { kCoreEventClass, kAEQuitApplication }, { kCoreEventClass, kAEOpenDocuments } }; +#ifndef QT_MAC_USE_COCOA /* watched events */ static EventTypeSpec app_events[] = { { kEventClassQt, kEventQtRequestWindowChange }, @@ -1156,13 +1156,13 @@ void qt_init(QApplicationPrivate *priv, int) qt_init_app_proc_handler(); } +#endif if (!app_proc_ae_handlerUPP) { app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor); for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, app_proc_ae_handlerUPP, SRefCon(qApp), true); } -#endif if (QApplicationPrivate::app_style) { QEvent ev(QEvent::Style); @@ -1210,6 +1210,17 @@ void qt_init(QApplicationPrivate *priv, int) } +void qt_release_apple_event_handler() +{ + if(app_proc_ae_handlerUPP) { + for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) + AERemoveEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, + app_proc_ae_handlerUPP, true); + DisposeAEEventHandlerUPP(app_proc_ae_handlerUPP); + app_proc_ae_handlerUPP = 0; + } +} + /***************************************************************************** qt_cleanup() - cleans up when the application is finished *****************************************************************************/ @@ -1223,15 +1234,8 @@ void qt_cleanup() DisposeEventHandlerUPP(app_proc_handlerUPP); app_proc_handlerUPP = 0; } - if(app_proc_ae_handlerUPP) { - for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) - AERemoveEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, - app_proc_ae_handlerUPP, true); - DisposeAEEventHandlerUPP(app_proc_ae_handlerUPP); - app_proc_ae_handlerUPP = NULL; - } #endif - + qt_release_apple_event_handler(); qt_release_tablet_proximity_handler(); if (tablet_proximity_UPP) DisposeEventHandlerUPP(tablet_proximity_UPP); @@ -2367,6 +2371,12 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event #endif } +// In Carbon this is your one stop for apple events. +// In Cocoa, it ISN'T. This is the catch-all Apple Event handler that exists +// for the time between instantiating the NSApplication, but before the +// NSApplication has installed it's OWN Apple Event handler. When Cocoa has +// that set up, we remove this. So, if you are debugging problems, you likely +// want to check out QCocoaApplicationDelegate instead. OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, AppleEvent *, long handlerRefcon) { QApplication *app = (QApplication *)handlerRefcon; diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index 6571068..dad15d9 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -204,6 +204,8 @@ static void cleanupCocoaApplicationDelegate() { Q_UNUSED(aNotification); inLaunch = false; + extern void qt_release_apple_event_handler(); //qapplication_mac.mm + qt_release_apple_event_handler(); } - (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames -- cgit v0.12 From c368a8ed6badab846c8e63c26d48b95788c12163 Mon Sep 17 00:00:00 2001 From: Trond Kjernaasen Date: Mon, 4 May 2009 14:01:07 +0200 Subject: Added an assert so that QColormap usage without a QApplication asserts. Task-number: 252668 Reviewed-by: Samuel --- src/gui/painting/qcolormap_win.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qcolormap_win.cpp b/src/gui/painting/qcolormap_win.cpp index d61b933..7d36582 100644 --- a/src/gui/painting/qcolormap_win.cpp +++ b/src/gui/painting/qcolormap_win.cpp @@ -138,7 +138,11 @@ void QColormap::cleanup() } QColormap QColormap::instance(int) -{ return QColormap(); } +{ + Q_ASSERT_X(screenMap, "QColormap", + "A QApplication object needs to be constructed before QColormap is used."); + return QColormap(); +} QColormap::QColormap() : d(screenMap) -- cgit v0.12 From 2ed015b8a0ffad63f0f59b0e2255057f416895fb Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 4 May 2009 14:24:45 +0200 Subject: Added a check that X11 timestamp goes forward only. Got a case somehow with a timestamp of the mouse event that is less than the timestamp we already had, so we need to make sure time only goes forward. Reviewed-by: Brad --- src/gui/kernel/qapplication_x11.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index f1fb001..15149a5 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -3169,43 +3169,48 @@ int QApplication::x11ProcessEvent(XEvent* event) #ifdef ALIEN_DEBUG //qDebug() << "QApplication::x11ProcessEvent:" << event->type; #endif + Time time = 0, userTime = 0; switch (event->type) { case ButtonPress: pressed_window = event->xbutton.window; - X11->userTime = event->xbutton.time; + userTime = event->xbutton.time; // fallthrough intended case ButtonRelease: - X11->time = event->xbutton.time; + time = event->xbutton.time; break; case MotionNotify: - X11->time = event->xmotion.time; + time = event->xmotion.time; break; case XKeyPress: - X11->userTime = event->xkey.time; + userTime = event->xkey.time; // fallthrough intended case XKeyRelease: - X11->time = event->xkey.time; + time = event->xkey.time; break; case PropertyNotify: - X11->time = event->xproperty.time; + time = event->xproperty.time; break; case EnterNotify: case LeaveNotify: - X11->time = event->xcrossing.time; + time = event->xcrossing.time; break; case SelectionClear: - X11->time = event->xselectionclear.time; + time = event->xselectionclear.time; break; default: - break; - } #ifndef QT_NO_XFIXES - if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) { - XFixesSelectionNotifyEvent *req = - reinterpret_cast(event); - X11->time = req->selection_timestamp; - } + if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) { + XFixesSelectionNotifyEvent *req = + reinterpret_cast(event); + time = req->selection_timestamp; + } #endif + break; + } + if (time > X11->time) + X11->time = time; + if (userTime > X11->userTime) + X11->userTime = userTime; QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window); -- cgit v0.12 From 0820be4a16f8213ba02e2a2f9fe5df4d1ec6a818 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Mon, 4 May 2009 15:20:15 +0200 Subject: Added function that was removed on the way from Qt3 to Qt4 QMimeSource::serialNumber was removed in Qt 4. This was not documented in Porting to Qt 4 Task-number:250575 Rev-By: Trenton Schulz --- doc/src/porting4.qdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/src/porting4.qdoc b/doc/src/porting4.qdoc index c8a9e2b..b93e139 100644 --- a/doc/src/porting4.qdoc +++ b/doc/src/porting4.qdoc @@ -457,6 +457,7 @@ \row \o QToolButton::offIconSet \o Use the \l{QIcon::Off}{off component} of QAbstractButton::icon instead. \row \o QToolButton::onIconSet \o Use the \l{QIcon::On}{on component} of QAbstractButton::icon instead. \row \o QWidget::microFocusHint \o N/A + \row \o QMimeSource::serialNumber () \o N/A \endtable \omit -- cgit v0.12 From a5c1161fb6bb2a24cebc104bc2a9b8def0a6e466 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Thu, 30 Apr 2009 16:59:37 +0200 Subject: QNetworkCookieJar: do not allow cookies for domains like ".com" the domain attribute in cookies must always contain one embedded dot, according to RFC 2109 section 4.3.2 Reviewed-by: Thiago Task-number: 251467 --- src/network/access/qnetworkcookie.cpp | 7 +++++++ tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index aaa5075..82c9344 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -1197,6 +1197,13 @@ bool QNetworkCookieJar::setCookiesFromUrl(const QList &cookieLis || isParentDomain(defaultDomain, domain))) { continue; // not accepted } + + // reject if domain is like ".com" + // (i.e., reject if domain does not contain embedded dots, see RFC 2109 section 4.3.2) + // this is just a rudimentary check and does not cover all cases + if (domain.lastIndexOf(QLatin1Char('.')) == 0) + continue; // not accepted + } QList::Iterator it = d->allCookies.begin(), diff --git a/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp index e87a3bf..7aa1d24 100644 --- a/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp +++ b/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp @@ -171,6 +171,17 @@ void tst_QNetworkCookieJar::setCookiesFromUrl_data() result.clear(); result += finalCookie; QTest::newRow("defaults-2") << preset << cookie << "http://www.foo.tld" << result << true; + + // security test: do not accept cookie domains like ".com" nor ".com." (see RFC 2109 section 4.3.2) + result.clear(); + preset.clear(); + cookie.setDomain(".com"); + QTest::newRow("rfc2109-4.3.2-ex3") << preset << cookie << "http://x.foo.com" << result << false; + + result.clear(); + preset.clear(); + cookie.setDomain(".com."); + QTest::newRow("rfc2109-4.3.2-ex3-2") << preset << cookie << "http://x.foo.com" << result << false; } void tst_QNetworkCookieJar::setCookiesFromUrl() -- cgit v0.12 From 885adf0541e4b709bf5a3774361e85db2a35fc47 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 4 May 2009 10:38:37 -0700 Subject: Lock for read only when possible From benchmarking I've established that surface->Lock(DSLF_READ) is faster than surface->Lock(DSLF_WRITE) which is faster than surface->Lock(DSLF_READ|DSLF_WRITE). This patch will make us Lock for read only, when possible. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbpaintdevice.cpp | 21 +++++++++++++-------- .../gfxdrivers/directfb/qdirectfbpaintdevice.h | 7 +++++-- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 4 ++-- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 12 +++++++++--- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h | 3 ++- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 6 +++--- src/plugins/gfxdrivers/directfb/qdirectfbscreen.h | 2 +- .../gfxdrivers/directfb/qdirectfbsurface.cpp | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbsurface.h | 8 ++++---- 9 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index 924090c..9796280 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -56,15 +56,20 @@ IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const } -void QDirectFBPaintDevice::lockDirectFB() +void QDirectFBPaintDevice::lockDirectFB(uint flags) { - if (lockedImage) - return; // Already locked - - if (uchar *mem = QDirectFBScreen::lockSurface(dfbSurface, DSLF_WRITE, &bpl)) { + if (lockedImage) { + if (lockFlags & flags) + return; + unlockDirectFB(); + } + if (uchar *mem = QDirectFBScreen::lockSurface(dfbSurface, flags, &bpl)) { const QSize s = size(); lockedImage = new QImage(mem, s.width(), s.height(), bpl, QDirectFBScreen::getImageFormat(dfbSurface)); + lockFlags = flags; + } else { + lockFlags = 0; } } @@ -80,10 +85,10 @@ void QDirectFBPaintDevice::unlockDirectFB() } -void* QDirectFBPaintDevice::memory() const +void *QDirectFBPaintDevice::memory() const { QDirectFBPaintDevice* that = const_cast(this); - that->lockDirectFB(); + that->lockDirectFB(DSLF_READ|DSLF_WRITE); Q_ASSERT(that->lockedImage); return that->lockedImage->bits(); } @@ -101,7 +106,7 @@ int QDirectFBPaintDevice::bytesPerLine() const // Can only get the stride when we lock the surface Q_ASSERT(!lockedImage); QDirectFBPaintDevice* that = const_cast(this); - that->lockDirectFB(); + that->lockDirectFB(DSLF_READ); Q_ASSERT(bpl != -1); } return bpl; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index a11064b..1709d69 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -58,7 +58,7 @@ public: IDirectFBSurface *directFBSurface() const; - void lockDirectFB(); + void lockDirectFB(uint flags); void unlockDirectFB(); inline bool forceRasterPrimitives() const { return forceRaster; } @@ -76,7 +76,9 @@ protected: dfbSurface(0), lockedImage(0), screen(scr), - forceRaster(false) {} + forceRaster(false), + lockFlags(0) + {} inline int dotsPerMeterX() const { @@ -92,6 +94,7 @@ protected: QDirectFBScreen *screen; int bpl; bool forceRaster; + uint lockFlags; private: Q_DISABLE_COPY(QDirectFBPaintDevice) }; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 14d2146..e9e2b1f 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -1040,7 +1040,7 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, QRasterPaintEngine::drawPixmap(r, pixmap, sr); } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) { RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); - const QImage *img = static_cast(pixmap.pixmapData())->buffer(); + const QImage *img = static_cast(pixmap.pixmapData())->buffer(DSLF_READ); d->lock(); QRasterPaintEngine::drawImage(r, *img, sr); } else { @@ -1066,7 +1066,7 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp); } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) { RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), sp); - const QImage *img = static_cast(pixmap.pixmapData())->buffer(); + const QImage *img = static_cast(pixmap.pixmapData())->buffer(DSLF_READ); d->lock(); QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType); data->fromImage(*img, Qt::AutoColor); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index ea9bb3a..f7c428b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -357,7 +357,7 @@ QImage QDirectFBPixmapData::toImage() const return img->copy(); } -QPaintEngine* QDirectFBPixmapData::paintEngine() const +QPaintEngine *QDirectFBPixmapData::paintEngine() const { if (!engine) { // QDirectFBPixmapData is also a QCustomRasterPaintDevice, so pass @@ -368,10 +368,15 @@ QPaintEngine* QDirectFBPixmapData::paintEngine() const return engine; } +QImage *QDirectFBPixmapData::buffer() +{ + lockDirectFB(DSLF_READ|DSLF_WRITE); + return lockedImage; +} -QImage* QDirectFBPixmapData::buffer() +QImage * QDirectFBPixmapData::buffer(uint lockFlags) { - lockDirectFB(); + lockDirectFB(lockFlags); return lockedImage; } @@ -381,3 +386,4 @@ void QDirectFBPixmapData::invalidate() alpha = false; format = QImage::Format_Invalid; } + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index 6cfafcd..697e5ce 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -69,7 +69,8 @@ public: Qt::TransformationMode mode) const; QImage toImage() const; QPaintEngine* paintEngine() const; - QImage *buffer(); + virtual QImage *buffer(); + QImage *buffer(uint lockFlags); // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index c1b75c5..9ec5f5f 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1336,12 +1336,12 @@ bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *d return true; } -uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl) +uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, uint flags, int *bpl) { void *mem; - const DFBResult result = surface->Lock(surface, flags, static_cast(&mem), bpl); + const DFBResult result = surface->Lock(surface, static_cast(flags), static_cast(&mem), bpl); if (result != DFB_OK) { - DirectFBError("QDirectFBPixmapData::lockSurface()", result); + DirectFBError("QDirectFBScreen::lockSurface()", result); } return reinterpret_cast(mem); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 42d0ebe..e91a06b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -137,7 +137,7 @@ public: const QImage &image); #endif - static uchar *lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl = 0); + static uchar *lockSurface(IDirectFBSurface *surface, uint flags, int *bpl = 0); private: void compose(const QRegion &r); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index beb9b5f..827e10d 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -423,7 +423,7 @@ void QDirectFBSurface::endPaint(const QRegion &) } -QImage* QDirectFBSurface::buffer(const QWidget *widget) +QImage *QDirectFBSurface::buffer(const QWidget *widget) { if (!lockedImage) return 0; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h index 54c14a5..c554096 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h @@ -58,7 +58,7 @@ QT_BEGIN_HEADER QT_MODULE(Gui) -class QDirectFBSurface: public QWSWindowSurface, public QDirectFBPaintDevice +class QDirectFBSurface : public QWSWindowSurface, public QDirectFBPaintDevice { public: QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); @@ -79,15 +79,15 @@ public: QRegion move(const QPoint &offset, const QRegion &newClip); QImage image() const { return QImage(); } - QPaintDevice* paintDevice() { return this; } - QPaintEngine* paintEngine() const; + QPaintDevice *paintDevice() { return this; } + QPaintEngine *paintEngine() const; void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); void beginPaint(const QRegion &); void endPaint(const QRegion &); - QImage* buffer(const QWidget *widget); + QImage *buffer(const QWidget *widget); private: #ifndef QT_NO_DIRECTFB_WM -- cgit v0.12 From f8f5fe02590da7e67829caf118ba73d455192ec8 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 4 May 2009 11:45:15 -0700 Subject: Rename QDirectFBSurface to QDirectFBWindowSurface This helps avoid confusion between IDirectFBSurface and QDirectFBSurface. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/directfb.pro | 4 +- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 2 +- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 12 +- .../gfxdrivers/directfb/qdirectfbsurface.cpp | 449 --------------------- src/plugins/gfxdrivers/directfb/qdirectfbsurface.h | 112 ----- .../gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 449 +++++++++++++++++++++ .../gfxdrivers/directfb/qdirectfbwindowsurface.h | 112 +++++ 7 files changed, 570 insertions(+), 570 deletions(-) delete mode 100644 src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp delete mode 100644 src/plugins/gfxdrivers/directfb/qdirectfbsurface.h create mode 100644 src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp create mode 100644 src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro index 67f5d61..abdb78f 100644 --- a/src/plugins/gfxdrivers/directfb/directfb.pro +++ b/src/plugins/gfxdrivers/directfb/directfb.pro @@ -22,7 +22,7 @@ target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers INSTALLS += target HEADERS = qdirectfbscreen.h \ - qdirectfbsurface.h \ + qdirectfbwindowsurface.h \ qdirectfbpaintengine.h \ qdirectfbpaintdevice.h \ qdirectfbpixmap.h \ @@ -31,7 +31,7 @@ HEADERS = qdirectfbscreen.h \ SOURCES = qdirectfbscreen.cpp \ qdirectfbscreenplugin.cpp \ - qdirectfbsurface.cpp \ + qdirectfbwindowsurface.cpp \ qdirectfbpaintengine.cpp \ qdirectfbpaintdevice.cpp \ qdirectfbpixmap.cpp \ diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index e9e2b1f..92f717e 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -43,7 +43,7 @@ #ifndef QT_NO_DIRECTFB -#include "qdirectfbsurface.h" +#include "qdirectfbwindowsurface.h" #include "qdirectfbscreen.h" #include "qdirectfbpixmap.h" #include diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 9ec5f5f..59f5934 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include "qdirectfbscreen.h" -#include "qdirectfbsurface.h" +#include "qdirectfbwindowsurface.h" #include "qdirectfbpixmap.h" #include "qdirectfbmouse.h" #include "qdirectfbkeyboard.h" @@ -1102,19 +1102,19 @@ QWSWindowSurface *QDirectFBScreen::createSurface(QWidget *widget) const { #ifdef QT_NO_DIRECTFB_WM if (QApplication::type() == QApplication::GuiServer) { - return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this), widget); + return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast(this), widget); } else { return QScreen::createSurface(widget); } #else - return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this), widget); + return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast(this), widget); #endif } QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const { if (key == QLatin1String("directfb")) { - return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this)); + return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast(this)); } return QScreen::createSurface(key); } @@ -1147,7 +1147,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) const QPoint offset = win->requestedRegion().boundingRect().topLeft(); if (surface->key() == QLatin1String("directfb")) { - QDirectFBSurface *s = static_cast(surface); + QDirectFBWindowSurface *s = static_cast(surface); blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); @@ -1196,7 +1196,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) const QPoint offset = win->requestedRegion().boundingRect().topLeft(); if (surface->key() == QLatin1String("directfb")) { - QDirectFBSurface *s = static_cast(surface); + QDirectFBWindowSurface *s = static_cast(surface); blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp deleted file mode 100644 index 827e10d..0000000 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, 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.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdirectfbsurface.h" -#include "qdirectfbscreen.h" -#include "qdirectfbpaintengine.h" - -#include -#include -#include - - -//#define QT_DIRECTFB_DEBUG_SURFACES 1 - -QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr) - : QDirectFBPaintDevice(scr) -#ifndef QT_NO_DIRECTFB_WM - , dfbWindow(0) -#endif - , engine(0) - , flipFlags(flip) - , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) -{ - setSurfaceFlags(Opaque | Buffered); -#ifdef QT_DIRECTFB_TIMING - frames = 0; - timer.start(); -#endif -} - -QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget) - : QWSWindowSurface(widget), QDirectFBPaintDevice(scr) -#ifndef QT_NO_DIRECTFB_WM - , dfbWindow(0) -#endif - , engine(0) - , flipFlags(flip) - , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) -{ - onscreen = widget->testAttribute(Qt::WA_PaintOnScreen); - if (onscreen) - setSurfaceFlags(Opaque | RegionReserved); - else - setSurfaceFlags(Opaque | Buffered); -#ifdef QT_DIRECTFB_TIMING - frames = 0; - timer.start(); -#endif -} - -QDirectFBSurface::~QDirectFBSurface() -{ -} - -bool QDirectFBSurface::isValid() const -{ - return true; -} - -#ifndef QT_NO_DIRECTFB_WM -void QDirectFBSurface::createWindow() -{ -#ifdef QT_NO_DIRECTFB_LAYER -#warning QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM -#else - IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); - if (!layer) - qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); - - DFBWindowDescription description; - description.caps = DFBWindowCapabilities(DWCAPS_NODECORATION); - description.flags = DFBWindowDescriptionFlags(DWDESC_CAPS - |DWDESC_SURFACE_CAPS - |DWDESC_PIXELFORMAT); - - description.surface_caps = DSCAPS_NONE; - if (screen->directFBFlags() & QDirectFBScreen::VideoOnly) - description.surface_caps = DFBSurfaceCapabilities(description.surface_caps|DSCAPS_VIDEOONLY); - const QImage::Format format = screen->pixelFormat(); - description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); - if (QDirectFBScreen::isPremultiplied(format)) - description.surface_caps = DFBSurfaceCapabilities(DSCAPS_PREMULTIPLIED|description.caps); - - DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow); - if (result != DFB_OK) - DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result); - - if (dfbSurface) - dfbSurface->Release(dfbSurface); - - dfbWindow->GetSurface(dfbWindow, &dfbSurface); - forceRaster = (format == QImage::Format_RGB32); -#endif -} -#endif // QT_NO_DIRECTFB_WM - -void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) -{ - if (rect.isNull()) { -#ifndef QT_NO_DIRECTFB_WM - if (dfbWindow) { - dfbWindow->Release(dfbWindow); - dfbWindow = 0; - } -#endif - if (dfbSurface && dfbSurface != screen->dfbSurface()) { - dfbSurface->Release(dfbSurface); - dfbSurface = 0; - } - } else if (rect != geometry()) { - DFBResult result = DFB_OK; - - // If we're in a resize, the surface shouldn't be locked - Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size())); - - if (onscreen) { - IDirectFBSurface *primarySurface = screen->dfbSurface(); - Q_ASSERT(primarySurface); - if (dfbSurface && dfbSurface != primarySurface) - dfbSurface->Release(dfbSurface); - - if (rect == screen->region().boundingRect()) { - dfbSurface = primarySurface; - } else { - const DFBRectangle r = { rect.x(), rect.y(), - rect.width(), rect.height() }; - result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); - } - forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); - } else { - const bool isResize = rect.size() != geometry().size(); -#ifdef QT_NO_DIRECTFB_WM - if (isResize) { - if (dfbSurface) - dfbSurface->Release(dfbSurface); - - IDirectFB *dfb = screen->dfb(); - if (!dfb) { - qFatal("QDirectFBWindowSurface::setGeometry(): " - "Unable to get DirectFB handle!"); - } - - DFBSurfaceDescription description; - description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | - DSDESC_HEIGHT | - DSDESC_PIXELFORMAT); - description.width = rect.width(); - description.height = rect.height(); - QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, - screen->pixelFormat()); - dfbSurface = screen->createDFBSurface(description, false); - forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); - } else { - Q_ASSERT(dfbSurface); - } -#else - const QRect oldRect = geometry(); - const bool isMove = oldRect.isEmpty() || - rect.topLeft() != oldRect.topLeft(); - - if (!dfbWindow) - createWindow(); - - if (isResize && isMove) - result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(), - rect.width(), rect.height()); - else if (isResize) - result = dfbWindow->Resize(dfbWindow, - rect.width(), rect.height()); - else if (isMove) - result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y()); -#endif - } - - if (result != DFB_OK) - DirectFBErrorFatal("QDirectFBSurface::setGeometry()", result); - } - - QWSWindowSurface::setGeometry(rect, mask); -} - -QByteArray QDirectFBSurface::permanentState() const -{ - QByteArray array; -#ifdef QT_NO_DIRECTFB_WM - array.resize(sizeof(SurfaceFlags) + sizeof(IDirectFBSurface*)); -#else - array.resize(sizeof(SurfaceFlags)); -#endif - char *ptr = array.data(); - - *reinterpret_cast(ptr) = surfaceFlags(); - ptr += sizeof(SurfaceFlags); - -#ifdef QT_NO_DIRECTFB_WM - *reinterpret_cast(ptr) = dfbSurface; -#endif - return array; -} - -void QDirectFBSurface::setPermanentState(const QByteArray &state) -{ - SurfaceFlags flags; - const char *ptr = state.constData(); - - flags = *reinterpret_cast(ptr); - setSurfaceFlags(flags); - -#ifdef QT_NO_DIRECTFB_WM - ptr += sizeof(SurfaceFlags); - dfbSurface = *reinterpret_cast(ptr); -#endif -} - -bool QDirectFBSurface::scroll(const QRegion ®ion, int dx, int dy) -{ - if (!dfbSurface || !(flipFlags & DSFLIP_BLIT)) - return false; - - const QVector rects = region.rects(); - const int n = rects.size(); - - QVarLengthArray dfbRects(n); - QVarLengthArray dfbPoints(n); - - for (int i = 0; i < n; ++i) { - const QRect r = rects.at(i); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); - dfbPoints[i].x = r.x() + dx; - dfbPoints[i].y = r.y() + dy; - } - - dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); - dfbSurface->BatchBlit(dfbSurface, dfbSurface, - dfbRects.data(), dfbPoints.data(), n); - dfbSurface->ReleaseSource(dfbSurface); - return true; -} - -bool QDirectFBSurface::move(const QPoint &offset) -{ - QWSWindowSurface::move(offset); - -#ifdef QT_NO_DIRECTFB_WM - return true; // buffered -#else - if (!dfbWindow) - return false; - - DFBResult status = dfbWindow->Move(dfbWindow, offset.x(), offset.y()); - return (status == DFB_OK); -#endif -} - -QRegion QDirectFBSurface::move(const QPoint &offset, const QRegion &newClip) -{ -#ifdef QT_NO_DIRECTFB_WM - return QWSWindowSurface::move(offset, newClip); -#else - Q_UNUSED(offset); - Q_UNUSED(newClip); - - // DirectFB handles the entire move, so there's no need to blit. - return QRegion(); -#endif -} - -QPaintEngine* QDirectFBSurface::paintEngine() const -{ - if (!engine) { - QDirectFBSurface *that = const_cast(this); - that->engine = new QDirectFBPaintEngine(that); - return that->engine; - } - return engine; -} - -// hw: XXX: copied from QWidgetPrivate::isOpaque() -inline bool isWidgetOpaque(const QWidget *w) -{ - if (w->testAttribute(Qt::WA_OpaquePaintEvent) - || w->testAttribute(Qt::WA_PaintOnScreen)) - return true; - - const QPalette &pal = w->palette(); - - if (w->autoFillBackground()) { - const QBrush &autoFillBrush = pal.brush(w->backgroundRole()); - if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) - return true; - } - - if (!w->testAttribute(Qt::WA_NoSystemBackground)) { - const QBrush &windowBrush = w->palette().brush(QPalette::Window); - if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) - return true; - } - - return false; -} -void QDirectFBSurface::flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset) -{ - Q_UNUSED(widget); -#ifdef QT_NO_DIRECTFB_WM - Q_UNUSED(region); - Q_UNUSED(offset); -#endif - - QWidget *win = window(); - - // hw: make sure opacity information is updated before compositing - const bool opaque = isWidgetOpaque(win); - if (opaque != isOpaque()) { - SurfaceFlags flags = Buffered; - if (opaque) - flags |= Opaque; - setSurfaceFlags(flags); - } - -#ifndef QT_NO_DIRECTFB_WM - const quint8 winOpacity = quint8(win->windowOpacity() * 255); - quint8 opacity; - - if (dfbWindow) { - dfbWindow->GetOpacity(dfbWindow, &opacity); - if (winOpacity != opacity) - dfbWindow->SetOpacity(dfbWindow, winOpacity); - } - if (!(flipFlags & DSFLIP_BLIT)) { - dfbSurface->Flip(dfbSurface, 0, flipFlags); - } else { - if (!boundingRectFlip && region.numRects() > 1) { - const QVector rects = region.rects(); - const DFBSurfaceFlipFlags nonWaitFlags = DFBSurfaceFlipFlags(flipFlags & ~DSFLIP_WAIT); - for (int i=0; iFlip(dfbSurface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags); - } - } else { - const QRect r = region.boundingRect(); - const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), - r.x() + r.width() + offset.x(), - r.y() + r.height() + offset.y() }; - dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags); - } - } -#endif -#ifdef QT_DIRECTFB_TIMING - enum { Secs = 3 }; - ++frames; - if (timer.elapsed() >= Secs * 1000) { - qDebug("%d fps", int(double(frames) / double(Secs))); - frames = 0; - timer.restart(); - } -#endif -} - - -void QDirectFBSurface::beginPaint(const QRegion &) -{ -} - -void QDirectFBSurface::endPaint(const QRegion &) -{ -#ifdef QT_DIRECTFB_DEBUG_SURFACES - if (bufferImages.count()) { - qDebug("QDirectFBSurface::endPaint() this=%p", this); - - foreach(QImage* bufferImg, bufferImages) - qDebug(" Deleting buffer image %p", bufferImg); - } -#endif - - qDeleteAll(bufferImages); - bufferImages.clear(); - unlockDirectFB(); -} - - -QImage *QDirectFBSurface::buffer(const QWidget *widget) -{ - if (!lockedImage) - return 0; - - const QRect rect = QRect(offset(widget), widget->size()) - & lockedImage->rect(); - if (rect.isEmpty()) - return 0; - - QImage *img = new QImage(lockedImage->scanLine(rect.y()) - + rect.x() * (lockedImage->depth() / 8), - rect.width(), rect.height(), - lockedImage->bytesPerLine(), - lockedImage->format()); - bufferImages.append(img); - -#ifdef QT_DIRECTFB_DEBUG_SURFACES - qDebug("QDirectFBSurface::buffer() Created & returned %p", img); -#endif - - return img; -} - diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h deleted file mode 100644 index c554096..0000000 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, 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.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDIRECFBWINDOWSURFACE_H -#define QDIRECFBWINDOWSURFACE_H - -#include "qdirectfbpaintengine.h" -#include "qdirectfbpaintdevice.h" -#include "qdirectfbscreen.h" - -#include -#include -#include - -#ifdef QT_DIRECTFB_TIMING -#include -#endif - -QT_BEGIN_HEADER - -QT_MODULE(Gui) - -class QDirectFBSurface : public QWSWindowSurface, public QDirectFBPaintDevice -{ -public: - QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); - QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget); - ~QDirectFBSurface(); - - bool isValid() const; - - void setGeometry(const QRect &rect, const QRegion &mask); - - QString key() const { return QLatin1String("directfb"); } - QByteArray permanentState() const; - void setPermanentState(const QByteArray &state); - - bool scroll(const QRegion &area, int dx, int dy); - - bool move(const QPoint &offset); - QRegion move(const QPoint &offset, const QRegion &newClip); - - QImage image() const { return QImage(); } - QPaintDevice *paintDevice() { return this; } - QPaintEngine *paintEngine() const; - - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - - void beginPaint(const QRegion &); - void endPaint(const QRegion &); - - QImage *buffer(const QWidget *widget); - -private: -#ifndef QT_NO_DIRECTFB_WM - void createWindow(); - IDirectFBWindow *dfbWindow; -#endif - QDirectFBPaintEngine *engine; - - bool onscreen; - - QList bufferImages; - DFBSurfaceFlipFlags flipFlags; - bool boundingRectFlip; -#ifdef QT_DIRECTFB_TIMING - int frames; - QTime timer; -#endif -}; - -QT_END_HEADER - -#endif // QDIRECFBWINDOWSURFACE_H diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp new file mode 100644 index 0000000..f1e3c84 --- /dev/null +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -0,0 +1,449 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdirectfbwindowsurface.h" +#include "qdirectfbscreen.h" +#include "qdirectfbpaintengine.h" + +#include +#include +#include + + +//#define QT_DIRECTFB_DEBUG_SURFACES 1 + +QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr) + : QDirectFBPaintDevice(scr) +#ifndef QT_NO_DIRECTFB_WM + , dfbWindow(0) +#endif + , engine(0) + , flipFlags(flip) + , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) +{ + setSurfaceFlags(Opaque | Buffered); +#ifdef QT_DIRECTFB_TIMING + frames = 0; + timer.start(); +#endif +} + +QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget) + : QWSWindowSurface(widget), QDirectFBPaintDevice(scr) +#ifndef QT_NO_DIRECTFB_WM + , dfbWindow(0) +#endif + , engine(0) + , flipFlags(flip) + , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) +{ + onscreen = widget->testAttribute(Qt::WA_PaintOnScreen); + if (onscreen) + setSurfaceFlags(Opaque | RegionReserved); + else + setSurfaceFlags(Opaque | Buffered); +#ifdef QT_DIRECTFB_TIMING + frames = 0; + timer.start(); +#endif +} + +QDirectFBWindowSurface::~QDirectFBWindowSurface() +{ +} + +bool QDirectFBWindowSurface::isValid() const +{ + return true; +} + +#ifndef QT_NO_DIRECTFB_WM +void QDirectFBWindowSurface::createWindow() +{ +#ifdef QT_NO_DIRECTFB_LAYER +#warning QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM +#else + IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); + if (!layer) + qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); + + DFBWindowDescription description; + description.caps = DFBWindowCapabilities(DWCAPS_NODECORATION); + description.flags = DFBWindowDescriptionFlags(DWDESC_CAPS + |DWDESC_SURFACE_CAPS + |DWDESC_PIXELFORMAT); + + description.surface_caps = DSCAPS_NONE; + if (screen->directFBFlags() & QDirectFBScreen::VideoOnly) + description.surface_caps = DFBSurfaceCapabilities(description.surface_caps|DSCAPS_VIDEOONLY); + const QImage::Format format = screen->pixelFormat(); + description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); + if (QDirectFBScreen::isPremultiplied(format)) + description.surface_caps = DFBSurfaceCapabilities(DSCAPS_PREMULTIPLIED|description.caps); + + DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow); + if (result != DFB_OK) + DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result); + + if (dfbSurface) + dfbSurface->Release(dfbSurface); + + dfbWindow->GetSurface(dfbWindow, &dfbSurface); + forceRaster = (format == QImage::Format_RGB32); +#endif +} +#endif // QT_NO_DIRECTFB_WM + +void QDirectFBWindowSurface::setGeometry(const QRect &rect, const QRegion &mask) +{ + if (rect.isNull()) { +#ifndef QT_NO_DIRECTFB_WM + if (dfbWindow) { + dfbWindow->Release(dfbWindow); + dfbWindow = 0; + } +#endif + if (dfbSurface && dfbSurface != screen->dfbSurface()) { + dfbSurface->Release(dfbSurface); + dfbSurface = 0; + } + } else if (rect != geometry()) { + DFBResult result = DFB_OK; + + // If we're in a resize, the surface shouldn't be locked + Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size())); + + if (onscreen) { + IDirectFBSurface *primarySurface = screen->dfbSurface(); + Q_ASSERT(primarySurface); + if (dfbSurface && dfbSurface != primarySurface) + dfbSurface->Release(dfbSurface); + + if (rect == screen->region().boundingRect()) { + dfbSurface = primarySurface; + } else { + const DFBRectangle r = { rect.x(), rect.y(), + rect.width(), rect.height() }; + result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); + } + forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); + } else { + const bool isResize = rect.size() != geometry().size(); +#ifdef QT_NO_DIRECTFB_WM + if (isResize) { + if (dfbSurface) + dfbSurface->Release(dfbSurface); + + IDirectFB *dfb = screen->dfb(); + if (!dfb) { + qFatal("QDirectFBWindowSurface::setGeometry(): " + "Unable to get DirectFB handle!"); + } + + DFBSurfaceDescription description; + description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | + DSDESC_HEIGHT | + DSDESC_PIXELFORMAT); + description.width = rect.width(); + description.height = rect.height(); + QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, + screen->pixelFormat()); + dfbSurface = screen->createDFBSurface(description, false); + forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); + } else { + Q_ASSERT(dfbSurface); + } +#else + const QRect oldRect = geometry(); + const bool isMove = oldRect.isEmpty() || + rect.topLeft() != oldRect.topLeft(); + + if (!dfbWindow) + createWindow(); + + if (isResize && isMove) + result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(), + rect.width(), rect.height()); + else if (isResize) + result = dfbWindow->Resize(dfbWindow, + rect.width(), rect.height()); + else if (isMove) + result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y()); +#endif + } + + if (result != DFB_OK) + DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); + } + + QWSWindowSurface::setGeometry(rect, mask); +} + +QByteArray QDirectFBWindowSurface::permanentState() const +{ + QByteArray array; +#ifdef QT_NO_DIRECTFB_WM + array.resize(sizeof(SurfaceFlags) + sizeof(IDirectFBSurface*)); +#else + array.resize(sizeof(SurfaceFlags)); +#endif + char *ptr = array.data(); + + *reinterpret_cast(ptr) = surfaceFlags(); + ptr += sizeof(SurfaceFlags); + +#ifdef QT_NO_DIRECTFB_WM + *reinterpret_cast(ptr) = dfbSurface; +#endif + return array; +} + +void QDirectFBWindowSurface::setPermanentState(const QByteArray &state) +{ + SurfaceFlags flags; + const char *ptr = state.constData(); + + flags = *reinterpret_cast(ptr); + setSurfaceFlags(flags); + +#ifdef QT_NO_DIRECTFB_WM + ptr += sizeof(SurfaceFlags); + dfbSurface = *reinterpret_cast(ptr); +#endif +} + +bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) +{ + if (!dfbSurface || !(flipFlags & DSFLIP_BLIT)) + return false; + + const QVector rects = region.rects(); + const int n = rects.size(); + + QVarLengthArray dfbRects(n); + QVarLengthArray dfbPoints(n); + + for (int i = 0; i < n; ++i) { + const QRect r = rects.at(i); + dfbRects[i].x = r.x(); + dfbRects[i].y = r.y(); + dfbRects[i].w = r.width(); + dfbRects[i].h = r.height(); + dfbPoints[i].x = r.x() + dx; + dfbPoints[i].y = r.y() + dy; + } + + dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); + dfbSurface->BatchBlit(dfbSurface, dfbSurface, + dfbRects.data(), dfbPoints.data(), n); + dfbSurface->ReleaseSource(dfbSurface); + return true; +} + +bool QDirectFBWindowSurface::move(const QPoint &offset) +{ + QWSWindowSurface::move(offset); + +#ifdef QT_NO_DIRECTFB_WM + return true; // buffered +#else + if (!dfbWindow) + return false; + + DFBResult status = dfbWindow->Move(dfbWindow, offset.x(), offset.y()); + return (status == DFB_OK); +#endif +} + +QRegion QDirectFBWindowSurface::move(const QPoint &offset, const QRegion &newClip) +{ +#ifdef QT_NO_DIRECTFB_WM + return QWSWindowSurface::move(offset, newClip); +#else + Q_UNUSED(offset); + Q_UNUSED(newClip); + + // DirectFB handles the entire move, so there's no need to blit. + return QRegion(); +#endif +} + +QPaintEngine* QDirectFBWindowSurface::paintEngine() const +{ + if (!engine) { + QDirectFBWindowSurface *that = const_cast(this); + that->engine = new QDirectFBPaintEngine(that); + return that->engine; + } + return engine; +} + +// hw: XXX: copied from QWidgetPrivate::isOpaque() +inline bool isWidgetOpaque(const QWidget *w) +{ + if (w->testAttribute(Qt::WA_OpaquePaintEvent) + || w->testAttribute(Qt::WA_PaintOnScreen)) + return true; + + const QPalette &pal = w->palette(); + + if (w->autoFillBackground()) { + const QBrush &autoFillBrush = pal.brush(w->backgroundRole()); + if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) + return true; + } + + if (!w->testAttribute(Qt::WA_NoSystemBackground)) { + const QBrush &windowBrush = w->palette().brush(QPalette::Window); + if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) + return true; + } + + return false; +} +void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, + const QPoint &offset) +{ + Q_UNUSED(widget); +#ifdef QT_NO_DIRECTFB_WM + Q_UNUSED(region); + Q_UNUSED(offset); +#endif + + QWidget *win = window(); + + // hw: make sure opacity information is updated before compositing + const bool opaque = isWidgetOpaque(win); + if (opaque != isOpaque()) { + SurfaceFlags flags = Buffered; + if (opaque) + flags |= Opaque; + setSurfaceFlags(flags); + } + +#ifndef QT_NO_DIRECTFB_WM + const quint8 winOpacity = quint8(win->windowOpacity() * 255); + quint8 opacity; + + if (dfbWindow) { + dfbWindow->GetOpacity(dfbWindow, &opacity); + if (winOpacity != opacity) + dfbWindow->SetOpacity(dfbWindow, winOpacity); + } + if (!(flipFlags & DSFLIP_BLIT)) { + dfbSurface->Flip(dfbSurface, 0, flipFlags); + } else { + if (!boundingRectFlip && region.numRects() > 1) { + const QVector rects = region.rects(); + const DFBSurfaceFlipFlags nonWaitFlags = DFBSurfaceFlipFlags(flipFlags & ~DSFLIP_WAIT); + for (int i=0; iFlip(dfbSurface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags); + } + } else { + const QRect r = region.boundingRect(); + const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), + r.x() + r.width() + offset.x(), + r.y() + r.height() + offset.y() }; + dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags); + } + } +#endif +#ifdef QT_DIRECTFB_TIMING + enum { Secs = 3 }; + ++frames; + if (timer.elapsed() >= Secs * 1000) { + qDebug("%d fps", int(double(frames) / double(Secs))); + frames = 0; + timer.restart(); + } +#endif +} + + +void QDirectFBWindowSurface::beginPaint(const QRegion &) +{ +} + +void QDirectFBWindowSurface::endPaint(const QRegion &) +{ +#ifdef QT_DIRECTFB_DEBUG_SURFACES + if (bufferImages.count()) { + qDebug("QDirectFBWindowSurface::endPaint() this=%p", this); + + foreach(QImage* bufferImg, bufferImages) + qDebug(" Deleting buffer image %p", bufferImg); + } +#endif + + qDeleteAll(bufferImages); + bufferImages.clear(); + unlockDirectFB(); +} + + +QImage *QDirectFBWindowSurface::buffer(const QWidget *widget) +{ + if (!lockedImage) + return 0; + + const QRect rect = QRect(offset(widget), widget->size()) + & lockedImage->rect(); + if (rect.isEmpty()) + return 0; + + QImage *img = new QImage(lockedImage->scanLine(rect.y()) + + rect.x() * (lockedImage->depth() / 8), + rect.width(), rect.height(), + lockedImage->bytesPerLine(), + lockedImage->format()); + bufferImages.append(img); + +#ifdef QT_DIRECTFB_DEBUG_SURFACES + qDebug("QDirectFBWindowSurface::buffer() Created & returned %p", img); +#endif + + return img; +} + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h new file mode 100644 index 0000000..75998c4 --- /dev/null +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDIRECFBWINDOWSURFACE_H +#define QDIRECFBWINDOWSURFACE_H + +#include "qdirectfbpaintengine.h" +#include "qdirectfbpaintdevice.h" +#include "qdirectfbscreen.h" + +#include +#include +#include + +#ifdef QT_DIRECTFB_TIMING +#include +#endif + +QT_BEGIN_HEADER + +QT_MODULE(Gui) + +class QDirectFBWindowSurface : public QWSWindowSurface, public QDirectFBPaintDevice +{ +public: + QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); + QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget); + ~QDirectFBWindowSurface(); + + bool isValid() const; + + void setGeometry(const QRect &rect, const QRegion &mask); + + QString key() const { return QLatin1String("directfb"); } + QByteArray permanentState() const; + void setPermanentState(const QByteArray &state); + + bool scroll(const QRegion &area, int dx, int dy); + + bool move(const QPoint &offset); + QRegion move(const QPoint &offset, const QRegion &newClip); + + QImage image() const { return QImage(); } + QPaintDevice *paintDevice() { return this; } + QPaintEngine *paintEngine() const; + + void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + + void beginPaint(const QRegion &); + void endPaint(const QRegion &); + + QImage *buffer(const QWidget *widget); + +private: +#ifndef QT_NO_DIRECTFB_WM + void createWindow(); + IDirectFBWindow *dfbWindow; +#endif + QDirectFBPaintEngine *engine; + + bool onscreen; + + QList bufferImages; + DFBSurfaceFlipFlags flipFlags; + bool boundingRectFlip; +#ifdef QT_DIRECTFB_TIMING + int frames; + QTime timer; +#endif +}; + +QT_END_HEADER + +#endif // QDIRECFBWINDOWSURFACE_H -- cgit v0.12