diff options
author | David Boddie <dboddie@trolltech.com> | 2010-06-28 11:10:40 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2010-06-28 11:10:40 (GMT) |
commit | 8f3cbe7e844ee49b1e25544d9b90218b00efa548 (patch) | |
tree | 73e501612ef8efdbfce8afbc5d8c6abe109190d3 /src | |
parent | 00cb03e2dfbcaca69da980dc79d5b062d4b09028 (diff) | |
parent | 5b90f7c27e7e4a95c75421fa42345b3268707794 (diff) | |
download | Qt-8f3cbe7e844ee49b1e25544d9b90218b00efa548.zip Qt-8f3cbe7e844ee49b1e25544d9b90218b00efa548.tar.gz Qt-8f3cbe7e844ee49b1e25544d9b90218b00efa548.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7
Diffstat (limited to 'src')
57 files changed, 1329 insertions, 874 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp index eafcc23..24873c8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp @@ -217,9 +217,7 @@ void Heap::destroy() NEVER_INLINE CollectorBlock* Heap::allocateBlock() { - // Disable the use of vm_map for the Qt build on Darwin, because when compiled on 10.4 - // it crashes on 10.5 -#if OS(DARWIN) && !PLATFORM(QT) +#if OS(DARWIN) vm_address_t address = 0; vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE | VM_TAG_FOR_COLLECTOR_MEMORY, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT); #elif OS(SYMBIAN) @@ -315,9 +313,7 @@ NEVER_INLINE void Heap::freeBlock(size_t block) NEVER_INLINE void Heap::freeBlockPtr(CollectorBlock* block) { - // Disable the use of vm_deallocate for the Qt build on Darwin, because when compiled on 10.4 - // it crashes on 10.5 -#if OS(DARWIN) && !PLATFORM(QT) +#if OS(DARWIN) vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE); #elif OS(SYMBIAN) userChunk->Free(reinterpret_cast<TAny*>(block)); diff --git a/src/3rdparty/javascriptcore/VERSION b/src/3rdparty/javascriptcore/VERSION index daecc37..4e01d20 100644 --- a/src/3rdparty/javascriptcore/VERSION +++ b/src/3rdparty/javascriptcore/VERSION @@ -4,8 +4,8 @@ This is a snapshot of JavaScriptCore from The commit imported was from the - javascriptcore-snapshot-16062010 branch/tag + javascriptcore-snapshot-28062010 branch/tag and has the sha1 checksum - 8b2d3443afca194f8ac50a63151dc9d19a150582 + f483443ccd7d21f2a57a794c4d00a63505d2f5d9 diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag index 1eb0d78..24cf142 100644 --- a/src/3rdparty/webkit/.tag +++ b/src/3rdparty/webkit/.tag @@ -1 +1 @@ -45d1c9149ef8940081fa8dd35854d2b95ebaf3cd +2f598e9b7b376d851fe089bc1dc729bcf0393a06 diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 676ed23..8fa3a72 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,37 @@ +2010-05-18 Anders Carlsson <andersca@apple.com> + + Reviewed by Sam Weinig. + + Add an inlineCapacity template parameter to ListHashSet and use it to shrink the positioned object list hash set. + https://bugs.webkit.org/show_bug.cgi?id=39304 + <rdar://problem/7998366> + + Add an inlineCapacity template parameter to ListHashSet. + + * wtf/ListHashSet.h: + (WTF::::ListHashSet): + (WTF::::operator): + (WTF::::swap): + (WTF::::~ListHashSet): + (WTF::::size): + (WTF::::capacity): + (WTF::::isEmpty): + (WTF::::begin): + (WTF::::end): + (WTF::::find): + (WTF::::contains): + (WTF::::add): + (WTF::::insertBefore): + (WTF::::remove): + (WTF::::clear): + (WTF::::unlinkAndDelete): + (WTF::::appendNode): + (WTF::::insertNodeBefore): + (WTF::::deleteAllNodes): + (WTF::::makeIterator): + (WTF::::makeConstIterator): + (WTF::deleteAllValues): + 2010-06-18 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/ListHashSet.h b/src/3rdparty/webkit/JavaScriptCore/wtf/ListHashSet.h index 54ed36b..09355ad 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/ListHashSet.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/ListHashSet.h @@ -37,27 +37,27 @@ namespace WTF { // and an append that moves the element to the end even if already present, // but unclear yet if these are needed. - template<typename Value, typename HashFunctions> class ListHashSet; + template<typename Value, size_t inlineCapacity, typename HashFunctions> class ListHashSet; template<typename T> struct IdentityExtractor; - template<typename Value, typename HashFunctions> - void deleteAllValues(const ListHashSet<Value, HashFunctions>&); + template<typename Value, size_t inlineCapacity, typename HashFunctions> + void deleteAllValues(const ListHashSet<Value, inlineCapacity, HashFunctions>&); - template<typename ValueArg, typename HashArg> class ListHashSetIterator; - template<typename ValueArg, typename HashArg> class ListHashSetConstIterator; + template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator; + template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator; - template<typename ValueArg> struct ListHashSetNode; - template<typename ValueArg> struct ListHashSetNodeAllocator; - template<typename ValueArg, typename HashArg> struct ListHashSetNodeHashFunctions; + template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode; + template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator; + template<typename ValueArg, size_t inlineCapacity, typename HashArg> struct ListHashSetNodeHashFunctions; - template<typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet : public FastAllocBase { + template<typename ValueArg, size_t inlineCapacity = 256, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet : public FastAllocBase { private: - typedef ListHashSetNode<ValueArg> Node; - typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator; + typedef ListHashSetNode<ValueArg, inlineCapacity> Node; + typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator; typedef HashTraits<Node*> NodeTraits; - typedef ListHashSetNodeHashFunctions<ValueArg, HashArg> NodeHash; + typedef ListHashSetNodeHashFunctions<ValueArg, inlineCapacity, HashArg> NodeHash; typedef HashTable<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplType; typedef HashTableIterator<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplTypeIterator; @@ -67,10 +67,10 @@ namespace WTF { public: typedef ValueArg ValueType; - typedef ListHashSetIterator<ValueType, HashArg> iterator; - typedef ListHashSetConstIterator<ValueType, HashArg> const_iterator; + typedef ListHashSetIterator<ValueType, inlineCapacity, HashArg> iterator; + typedef ListHashSetConstIterator<ValueType, inlineCapacity, HashArg> const_iterator; - friend class ListHashSetConstIterator<ValueType, HashArg>; + friend class ListHashSetConstIterator<ValueType, inlineCapacity, HashArg>; ListHashSet(); ListHashSet(const ListHashSet&); @@ -119,9 +119,9 @@ namespace WTF { OwnPtr<NodeAllocator> m_allocator; }; - template<typename ValueArg> struct ListHashSetNodeAllocator { - typedef ListHashSetNode<ValueArg> Node; - typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator; + template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator { + typedef ListHashSetNode<ValueArg, inlineCapacity> Node; + typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator; ListHashSetNodeAllocator() : m_freeList(pool()) @@ -181,15 +181,15 @@ namespace WTF { Node* m_freeList; bool m_isDoneWithInitialFreeList; - static const size_t m_poolSize = 256; + static const size_t m_poolSize = inlineCapacity; union { char pool[sizeof(Node) * m_poolSize]; double forAlignment; } m_pool; }; - template<typename ValueArg> struct ListHashSetNode { - typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator; + template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode { + typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator; ListHashSetNode(ValueArg value) : m_value(value) @@ -220,25 +220,25 @@ namespace WTF { #endif }; - template<typename ValueArg, typename HashArg> struct ListHashSetNodeHashFunctions { - typedef ListHashSetNode<ValueArg> Node; + template<typename ValueArg, size_t inlineCapacity, typename HashArg> struct ListHashSetNodeHashFunctions { + typedef ListHashSetNode<ValueArg, inlineCapacity> Node; static unsigned hash(Node* const& key) { return HashArg::hash(key->m_value); } static bool equal(Node* const& a, Node* const& b) { return HashArg::equal(a->m_value, b->m_value); } static const bool safeToCompareToEmptyOrDeleted = false; }; - template<typename ValueArg, typename HashArg> class ListHashSetIterator { + template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator { private: - typedef ListHashSet<ValueArg, HashArg> ListHashSetType; - typedef ListHashSetIterator<ValueArg, HashArg> iterator; - typedef ListHashSetConstIterator<ValueArg, HashArg> const_iterator; - typedef ListHashSetNode<ValueArg> Node; + typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType; + typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator; + typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator; + typedef ListHashSetNode<ValueArg, inlineCapacity> Node; typedef ValueArg ValueType; typedef ValueType& ReferenceType; typedef ValueType* PointerType; - friend class ListHashSet<ValueArg, HashArg>; + friend class ListHashSet<ValueArg, inlineCapacity, HashArg>; ListHashSetIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { } @@ -271,18 +271,18 @@ namespace WTF { const_iterator m_iterator; }; - template<typename ValueArg, typename HashArg> class ListHashSetConstIterator { + template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator { private: - typedef ListHashSet<ValueArg, HashArg> ListHashSetType; - typedef ListHashSetIterator<ValueArg, HashArg> iterator; - typedef ListHashSetConstIterator<ValueArg, HashArg> const_iterator; - typedef ListHashSetNode<ValueArg> Node; + typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType; + typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator; + typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator; + typedef ListHashSetNode<ValueArg, inlineCapacity> Node; typedef ValueArg ValueType; typedef const ValueType& ReferenceType; typedef const ValueType* PointerType; - friend class ListHashSet<ValueArg, HashArg>; - friend class ListHashSetIterator<ValueArg, HashArg>; + friend class ListHashSet<ValueArg, inlineCapacity, HashArg>; + friend class ListHashSetIterator<ValueArg, inlineCapacity, HashArg>; ListHashSetConstIterator(const ListHashSetType* set, Node* position) : m_set(set) @@ -341,11 +341,11 @@ namespace WTF { }; - template<typename ValueType, typename HashFunctions> + template<typename ValueType, size_t inlineCapacity, typename HashFunctions> struct ListHashSetTranslator { private: - typedef ListHashSetNode<ValueType> Node; - typedef ListHashSetNodeAllocator<ValueType> NodeAllocator; + typedef ListHashSetNode<ValueType, inlineCapacity> Node; + typedef ListHashSetNodeAllocator<ValueType, inlineCapacity> NodeAllocator; public: static unsigned hash(const ValueType& key) { return HashFunctions::hash(key); } static bool equal(Node* const& a, const ValueType& b) { return HashFunctions::equal(a->m_value, b); } @@ -355,16 +355,16 @@ namespace WTF { } }; - template<typename T, typename U> - inline ListHashSet<T, U>::ListHashSet() + template<typename T, size_t inlineCapacity, typename U> + inline ListHashSet<T, inlineCapacity, U>::ListHashSet() : m_head(0) , m_tail(0) , m_allocator(new NodeAllocator) { } - template<typename T, typename U> - inline ListHashSet<T, U>::ListHashSet(const ListHashSet& other) + template<typename T, size_t inlineCapacity, typename U> + inline ListHashSet<T, inlineCapacity, U>::ListHashSet(const ListHashSet& other) : m_head(0) , m_tail(0) , m_allocator(new NodeAllocator) @@ -374,16 +374,16 @@ namespace WTF { add(*it); } - template<typename T, typename U> - inline ListHashSet<T, U>& ListHashSet<T, U>::operator=(const ListHashSet& other) + template<typename T, size_t inlineCapacity, typename U> + inline ListHashSet<T, inlineCapacity, U>& ListHashSet<T, inlineCapacity, U>::operator=(const ListHashSet& other) { ListHashSet tmp(other); swap(tmp); return *this; } - template<typename T, typename U> - inline void ListHashSet<T, U>::swap(ListHashSet& other) + template<typename T, size_t inlineCapacity, typename U> + inline void ListHashSet<T, inlineCapacity, U>::swap(ListHashSet& other) { m_impl.swap(other.m_impl); std::swap(m_head, other.m_head); @@ -391,95 +391,95 @@ namespace WTF { m_allocator.swap(other.m_allocator); } - template<typename T, typename U> - inline ListHashSet<T, U>::~ListHashSet() + template<typename T, size_t inlineCapacity, typename U> + inline ListHashSet<T, inlineCapacity, U>::~ListHashSet() { deleteAllNodes(); } - template<typename T, typename U> - inline int ListHashSet<T, U>::size() const + template<typename T, size_t inlineCapacity, typename U> + inline int ListHashSet<T, inlineCapacity, U>::size() const { return m_impl.size(); } - template<typename T, typename U> - inline int ListHashSet<T, U>::capacity() const + template<typename T, size_t inlineCapacity, typename U> + inline int ListHashSet<T, inlineCapacity, U>::capacity() const { return m_impl.capacity(); } - template<typename T, typename U> - inline bool ListHashSet<T, U>::isEmpty() const + template<typename T, size_t inlineCapacity, typename U> + inline bool ListHashSet<T, inlineCapacity, U>::isEmpty() const { return m_impl.isEmpty(); } - template<typename T, typename U> - inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::begin() + template<typename T, size_t inlineCapacity, typename U> + inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::begin() { return makeIterator(m_head); } - template<typename T, typename U> - inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::end() + template<typename T, size_t inlineCapacity, typename U> + inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::end() { return makeIterator(0); } - template<typename T, typename U> - inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::begin() const + template<typename T, size_t inlineCapacity, typename U> + inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::begin() const { return makeConstIterator(m_head); } - template<typename T, typename U> - inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::end() const + template<typename T, size_t inlineCapacity, typename U> + inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::end() const { return makeConstIterator(0); } - template<typename T, typename U> - inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::find(const ValueType& value) + template<typename T, size_t inlineCapacity, typename U> + inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value) { - typedef ListHashSetTranslator<ValueType, HashFunctions> Translator; + typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; ImplTypeIterator it = m_impl.template find<ValueType, Translator>(value); if (it == m_impl.end()) return end(); return makeIterator(*it); } - template<typename T, typename U> - inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::find(const ValueType& value) const + template<typename T, size_t inlineCapacity, typename U> + inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value) const { - typedef ListHashSetTranslator<ValueType, HashFunctions> Translator; + typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; ImplTypeConstIterator it = m_impl.template find<ValueType, Translator>(value); if (it == m_impl.end()) return end(); return makeConstIterator(*it); } - template<typename T, typename U> - inline bool ListHashSet<T, U>::contains(const ValueType& value) const + template<typename T, size_t inlineCapacity, typename U> + inline bool ListHashSet<T, inlineCapacity, U>::contains(const ValueType& value) const { - typedef ListHashSetTranslator<ValueType, HashFunctions> Translator; + typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; return m_impl.template contains<ValueType, Translator>(value); } - template<typename T, typename U> - pair<typename ListHashSet<T, U>::iterator, bool> ListHashSet<T, U>::add(const ValueType &value) + template<typename T, size_t inlineCapacity, typename U> + pair<typename ListHashSet<T, inlineCapacity, U>::iterator, bool> ListHashSet<T, inlineCapacity, U>::add(const ValueType &value) { - typedef ListHashSetTranslator<ValueType, HashFunctions> Translator; + typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; pair<typename ImplType::iterator, bool> result = m_impl.template add<ValueType, NodeAllocator*, Translator>(value, m_allocator.get()); if (result.second) appendNode(*result.first); return std::make_pair(makeIterator(*result.first), result.second); } - template<typename T, typename U> - pair<typename ListHashSet<T, U>::iterator, bool> ListHashSet<T, U>::insertBefore(iterator it, const ValueType& newValue) + template<typename T, size_t inlineCapacity, typename U> + pair<typename ListHashSet<T, inlineCapacity, U>::iterator, bool> ListHashSet<T, inlineCapacity, U>::insertBefore(iterator it, const ValueType& newValue) { - typedef ListHashSetTranslator<ValueType, HashFunctions> Translator; + typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; pair<typename ImplType::iterator, bool> result = m_impl.template add<ValueType, NodeAllocator*, Translator>(newValue, m_allocator.get()); if (result.second) insertNodeBefore(it.node(), *result.first); @@ -487,14 +487,14 @@ namespace WTF { } - template<typename T, typename U> - pair<typename ListHashSet<T, U>::iterator, bool> ListHashSet<T, U>::insertBefore(const ValueType& beforeValue, const ValueType& newValue) + template<typename T, size_t inlineCapacity, typename U> + pair<typename ListHashSet<T, inlineCapacity, U>::iterator, bool> ListHashSet<T, inlineCapacity, U>::insertBefore(const ValueType& beforeValue, const ValueType& newValue) { return insertBefore(find(beforeValue), newValue); } - template<typename T, typename U> - inline void ListHashSet<T, U>::remove(iterator it) + template<typename T, size_t inlineCapacity, typename U> + inline void ListHashSet<T, inlineCapacity, U>::remove(iterator it) { if (it == end()) return; @@ -502,14 +502,14 @@ namespace WTF { unlinkAndDelete(it.node()); } - template<typename T, typename U> - inline void ListHashSet<T, U>::remove(const ValueType& value) + template<typename T, size_t inlineCapacity, typename U> + inline void ListHashSet<T, inlineCapacity, U>::remove(const ValueType& value) { remove(find(value)); } - template<typename T, typename U> - inline void ListHashSet<T, U>::clear() + template<typename T, size_t inlineCapacity, typename U> + inline void ListHashSet<T, inlineCapacity, U>::clear() { deleteAllNodes(); m_impl.clear(); @@ -517,8 +517,8 @@ namespace WTF { m_tail = 0; } - template<typename T, typename U> - void ListHashSet<T, U>::unlinkAndDelete(Node* node) + template<typename T, size_t inlineCapacity, typename U> + void ListHashSet<T, inlineCapacity, U>::unlinkAndDelete(Node* node) { if (!node->m_prev) { ASSERT(node == m_head); @@ -539,8 +539,8 @@ namespace WTF { node->destroy(m_allocator.get()); } - template<typename T, typename U> - void ListHashSet<T, U>::appendNode(Node* node) + template<typename T, size_t inlineCapacity, typename U> + void ListHashSet<T, inlineCapacity, U>::appendNode(Node* node) { node->m_prev = m_tail; node->m_next = 0; @@ -556,8 +556,8 @@ namespace WTF { m_tail = node; } - template<typename T, typename U> - void ListHashSet<T, U>::insertNodeBefore(Node* beforeNode, Node* newNode) + template<typename T, size_t inlineCapacity, typename U> + void ListHashSet<T, inlineCapacity, U>::insertNodeBefore(Node* beforeNode, Node* newNode) { if (!beforeNode) return appendNode(newNode); @@ -572,8 +572,8 @@ namespace WTF { m_head = newNode; } - template<typename T, typename U> - void ListHashSet<T, U>::deleteAllNodes() + template<typename T, size_t inlineCapacity, typename U> + void ListHashSet<T, inlineCapacity, U>::deleteAllNodes() { if (!m_head) return; @@ -582,16 +582,16 @@ namespace WTF { node->destroy(m_allocator.get()); } - template<typename T, typename U> - inline ListHashSetIterator<T, U> ListHashSet<T, U>::makeIterator(Node* position) + template<typename T, size_t inlineCapacity, typename U> + inline ListHashSetIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeIterator(Node* position) { - return ListHashSetIterator<T, U>(this, position); + return ListHashSetIterator<T, inlineCapacity, U>(this, position); } - template<typename T, typename U> - inline ListHashSetConstIterator<T, U> ListHashSet<T, U>::makeConstIterator(Node* position) const + template<typename T, size_t inlineCapacity, typename U> + inline ListHashSetConstIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeConstIterator(Node* position) const { - return ListHashSetConstIterator<T, U>(this, position); + return ListHashSetConstIterator<T, inlineCapacity, U>(this, position); } template<bool, typename ValueType, typename HashTableType> @@ -603,10 +603,10 @@ namespace WTF { delete (*it)->m_value; } - template<typename T, typename U> - inline void deleteAllValues(const ListHashSet<T, U>& collection) + template<typename T, size_t inlineCapacity, typename U> + inline void deleteAllValues(const ListHashSet<T, inlineCapacity, U>& collection) { - deleteAllValues<true, typename ListHashSet<T, U>::ValueType>(collection.m_impl); + deleteAllValues<true, typename ListHashSet<T, inlineCapacity, U>::ValueType>(collection.m_impl); } } // namespace WTF diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 1a343eb..924b120 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from and has the sha1 checksum - 45d1c9149ef8940081fa8dd35854d2b95ebaf3cd + 2f598e9b7b376d851fe089bc1dc729bcf0393a06 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index fd259e0..a84f177 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,90 @@ +2010-06-24 Simon Hausmann <simon.hausmann@nokia.com> + + Unreviewed Symbian build fix. + + The QML WebKit integration needs to be part of QtWebKit.sis + + * WebCore.pro: Deploy qmlwebkitplugin.dll. + +2010-06-23 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Do not render the full frame when there is some elements with fixed positioning + https://bugs.webkit.org/show_bug.cgi?id=33150 + + Do not render the full frame when there is some elements with fixed positioning + https://bugs.webkit.org/show_bug.cgi?id=33150 + + The frame view take into acount the list of fixed object when scrolling + the view. If the number of object is lower than a certain threshold, the pixel + are blitted, and the invalidated area updated. + + * page/FrameView.cpp: + (WebCore::FrameView::addFixedObject): + (WebCore::FrameView::removeFixedObject): + (WebCore::FrameView::scrollContentsFastPath): + * page/FrameView.h: + * platform/ScrollView.cpp: + (WebCore::ScrollView::scrollContents): + (WebCore::ScrollView::scrollContentsFastPath): + * platform/ScrollView.h: + * rendering/RenderLayer.cpp: + (WebCore::RenderLayer::repaintRectIncludingDescendants): + * rendering/RenderLayer.h: + * rendering/RenderObject.cpp: + (WebCore::RenderObject::styleWillChange): + +2010-05-18 Anders Carlsson <andersca@apple.com> + + Reviewed by Sam Weinig. + + Allocate the m_preloads list hash set dynamically and free it when done. + https://bugs.webkit.org/show_bug.cgi?id=39309 + <rdar://problem/7998495> + + This saves about 6000 bytes on a fully loaded document. + + * loader/DocLoader.cpp: + (WebCore::DocLoader::requestPreload): + (WebCore::DocLoader::clearPreloads): + * loader/DocLoader.h: + +2010-05-18 Anders Carlsson <andersca@apple.com> + + Revert unintended indentation and unnecessary nested name specifier. + + * rendering/RenderBlock.cpp: + (WebCore::clipOutPositionedObjects): + (WebCore::RenderBlock::insertPositionedObject): + +2010-05-18 Anders Carlsson <andersca@apple.com> + + Reviewed by Sam Weinig. + + Add an inlineCapacity template parameter to ListHashSet and use it to shrink the positioned object list hash set. + https://bugs.webkit.org/show_bug.cgi?id=39304 + <rdar://problem/7998366> + + Set the inlineCapacity for the positionedObjects ListHashSet to 4 instead of 256. Since a RenderBlock usually has + few positioned objects, this saves memory. + + * WebCore.base.exp: + * rendering/RenderBlock.cpp: + (WebCore::clipOutPositionedObjects): + (WebCore::RenderBlock::insertPositionedObject): + * rendering/RenderBlock.h: + (WebCore::RenderBlock::positionedObjects): + +2010-06-22 Simon Hausmann <simon.hausmann@nokia.com> + + Unreviewed Qt/Symbian build fix. + + Fix "make clean" to not try to execute clean commands for + the extra targets we use to simulate "make install". + + * WebCore.pro: Use no_clean in CONFIG of extra compilers. + 2010-06-21 Balazs Kelemen <kb@inf.u-szeged.hu> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index e0b4905..1162a52 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -25,6 +25,13 @@ symbian: { webkitbackup.sources = ../WebKit/qt/symbian/backup_registration.xml webkitbackup.path = /private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) + contains(QT_CONFIG, declarative) { + declarativeImport.sources = qmlwebkitplugin$${QT_LIBINFIX}.dll + declarativeImport.sources += ../WebKit/qt/declarative/qmldir + declarativeImport.path = c:$$QT_IMPORTS_BASE_DIR/QtWebKit + DEPLOYMENT += declarativeImport + } + DEPLOYMENT += webkitlibs webkitbackup # Need to guarantee that these come before system includes of /epoc32/include @@ -2866,6 +2873,7 @@ HEADERS += $$WEBKIT_API_HEADERS # INSTALLS is not implemented in qmake's s60 generators, copy headers manually inst_headers.commands = $$QMAKE_COPY ${QMAKE_FILE_NAME} ${QMAKE_FILE_OUT} inst_headers.input = WEBKIT_INSTALL_HEADERS + inst_headers.CONFIG = no_clean !isEmpty(INSTALL_HEADERS): inst_headers.output = $$INSTALL_HEADERS/QtWebKit/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} else: inst_headers.output = $$[QT_INSTALL_HEADERS]/QtWebKit/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} @@ -2875,6 +2883,7 @@ HEADERS += $$WEBKIT_API_HEADERS inst_modfile.commands = $$inst_headers.commands inst_modfile.input = moduleFile inst_modfile.output = $$[QMAKE_MKSPECS]/modules + inst_modfile.CONFIG = no_clean QMAKE_EXTRA_COMPILERS += inst_modfile diff --git a/src/3rdparty/webkit/WebCore/loader/DocLoader.cpp b/src/3rdparty/webkit/WebCore/loader/DocLoader.cpp index 0053e7b..4597704 100644 --- a/src/3rdparty/webkit/WebCore/loader/DocLoader.cpp +++ b/src/3rdparty/webkit/WebCore/loader/DocLoader.cpp @@ -407,10 +407,14 @@ void DocLoader::requestPreload(CachedResource::Type type, const String& url, con encoding = charset.isEmpty() ? m_doc->frame()->loader()->encoding() : charset; CachedResource* resource = requestResource(type, url, encoding, true); - if (!resource || m_preloads.contains(resource)) + if (!resource || (m_preloads && m_preloads->contains(resource))) return; resource->increasePreloadCount(); - m_preloads.add(resource); + + if (!m_preloads) + m_preloads.set(new ListHashSet<CachedResource*>); + m_preloads->add(resource); + #if PRELOAD_DEBUG printf("PRELOADING %s\n", resource->url().latin1().data()); #endif @@ -421,8 +425,11 @@ void DocLoader::clearPreloads() #if PRELOAD_DEBUG printPreloadStats(); #endif - ListHashSet<CachedResource*>::iterator end = m_preloads.end(); - for (ListHashSet<CachedResource*>::iterator it = m_preloads.begin(); it != end; ++it) { + if (!m_preloads) + return; + + ListHashSet<CachedResource*>::iterator end = m_preloads->end(); + for (ListHashSet<CachedResource*>::iterator it = m_preloads->begin(); it != end; ++it) { CachedResource* res = *it; res->decreasePreloadCount(); if (res->canDelete() && !res->inCache()) diff --git a/src/3rdparty/webkit/WebCore/loader/DocLoader.h b/src/3rdparty/webkit/WebCore/loader/DocLoader.h index 8ec73e1..66e4164 100644 --- a/src/3rdparty/webkit/WebCore/loader/DocLoader.h +++ b/src/3rdparty/webkit/WebCore/loader/DocLoader.h @@ -47,8 +47,7 @@ class ImageLoader; class KURL; // The DocLoader manages the loading of scripts/images/stylesheets for a single document. -class DocLoader : public Noncopyable -{ +class DocLoader : public Noncopyable { friend class Cache; friend class ImageLoader; @@ -117,7 +116,7 @@ private: int m_requestCount; - ListHashSet<CachedResource*> m_preloads; + OwnPtr<ListHashSet<CachedResource*> > m_preloads; struct PendingPreload { CachedResource::Type m_type; String m_url; diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp index a53db36..639414b 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp +++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp @@ -884,7 +884,7 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect { const size_t fixedObjectThreshold = 5; - ListHashSet<RenderBox*>* positionedObjects = 0; + RenderBlock::PositionedObjectsListHashSet* positionedObjects = 0; if (RenderView* root = m_frame->contentRenderer()) positionedObjects = root->positionedObjects(); @@ -896,14 +896,14 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect // Get the rects of the fixed objects visible in the rectToScroll Vector<IntRect, fixedObjectThreshold> subRectToUpdate; bool updateInvalidatedSubRect = true; - ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end(); - for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) { + RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end(); + for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) { RenderBox* renderBox = *it; if (renderBox->style()->position() != FixedPosition) continue; - IntRect topLevelRect; - IntRect updateRect = renderBox->paintingRootRect(topLevelRect); - updateRect.move(-scrollX(), -scrollY()); + IntRect updateRect = renderBox->layer()->repaintRectIncludingDescendants(); + updateRect = contentsToWindow(updateRect); + updateRect.intersect(rectToScroll); if (!updateRect.isEmpty()) { if (subRectToUpdate.size() >= fixedObjectThreshold) { diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp index a7b8a02..798663e 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp @@ -1982,13 +1982,13 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty) } #ifndef BUILDING_ON_TIGER -static void clipOutPositionedObjects(const RenderObject::PaintInfo* paintInfo, int tx, int ty, ListHashSet<RenderBox*>* positionedObjects) +static void clipOutPositionedObjects(const RenderObject::PaintInfo* paintInfo, int tx, int ty, RenderBlock::PositionedObjectsListHashSet* positionedObjects) { if (!positionedObjects) return; - ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end(); - for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) { + RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end(); + for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) { RenderBox* r = *it; paintInfo->context->clipOut(IntRect(tx + r->x(), ty + r->y(), r->width(), r->height())); } @@ -2274,7 +2274,7 @@ void RenderBlock::insertPositionedObject(RenderBox* o) { // Create the list of special objects if we don't aleady have one if (!m_positionedObjects) - m_positionedObjects = new ListHashSet<RenderBox*>; + m_positionedObjects = new PositionedObjectsListHashSet; m_positionedObjects->add(o); } diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h index 184f983..d555d31 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h @@ -74,7 +74,9 @@ public: void insertPositionedObject(RenderBox*); void removePositionedObject(RenderBox*); void removePositionedObjects(RenderBlock*); - ListHashSet<RenderBox*>* positionedObjects() const { return m_positionedObjects; } + + typedef ListHashSet<RenderBox*, 4> PositionedObjectsListHashSet; + PositionedObjectsListHashSet* positionedObjects() const { return m_positionedObjects; } void addPercentHeightDescendant(RenderBox*); static void removePercentHeightDescendant(RenderBox*); @@ -483,9 +485,10 @@ private: void setCollapsedBottomMargin(const MarginInfo&); // End helper functions and structs used by layoutBlockChildren. - typedef ListHashSet<RenderBox*>::const_iterator Iterator; + typedef PositionedObjectsListHashSet::const_iterator Iterator; DeprecatedPtrList<FloatingObject>* m_floatingObjects; - ListHashSet<RenderBox*>* m_positionedObjects; + + PositionedObjectsListHashSet* m_positionedObjects; // An inline can be split with blocks occurring in between the inline content. // When this occurs we need a pointer to our next object. We can basically be diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp index 3314772..a012868 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp @@ -325,6 +325,14 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags) m_marquee->updateMarqueePosition(); } +IntRect RenderLayer::repaintRectIncludingDescendants() const +{ + IntRect repaintRect = m_repaintRect; + for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) + repaintRect.unite(child->repaintRectIncludingDescendants()); + return repaintRect; +} + void RenderLayer::computeRepaintRects() { RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint(); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h index 81a66e1..e221f28 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h @@ -394,6 +394,7 @@ public: // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint. IntRect repaintRect() const { return m_repaintRect; } + IntRect repaintRectIncludingDescendants() const; void computeRepaintRects(); void updateRepaintRectsAfterScroll(bool fixed = false); void setNeedsFullRepaint(bool f = true) { m_needsFullRepaint = f; } diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index 0e73680..69a431f 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,47 @@ +2010-06-24 Simon Hausmann <simon.hausmann@nokia.com> + + Unreviewed Symbian build fix. + + The QML WebKit integration needs to be part of QtWebKit.sis + + * declarative/declarative.pro: Removed non-working deployment. + +2010-06-23 David Boddie <dboddie@trolltech.com> + + Reviewed by Simon Hausmann. + + [Qt] Doc: Fixed documentation errors. + + * docs/qtwebkit-bridge.qdoc: + +2010-06-23 Alessandro Portale <alessandro.portale@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Provide the Webkit Qml plugin with a UID3 on Symbian + + ...otherwise we cannot Symbian sign it. + + * declarative/declarative.pro: + +2010-06-23 Simon Hausmann <simon.hausmann@nokia.com> + + Unreviewed Qt package build fix. + + When building without build-webkit, set OUTPUT_DIR if necessary, like + in the other .pro files. + + * declarative/declarative.pro: + +2010-06-22 Tasuku Suzuki <tasuku.suzuki@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with QT_NO_COMBOBOX. + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::createSelectPopup): + 2010-06-11 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> Reviewed by nobody, build fix. diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index 7d1c794..e253161 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -576,7 +576,7 @@ QtAbstractWebPopup* ChromeClientQt::createSelectPopup() #elif !defined(QT_NO_COMBOBOX) return new QtFallbackWebPopup; #else - return result; + return 0; #endif } diff --git a/src/3rdparty/webkit/WebKit/qt/declarative/declarative.pro b/src/3rdparty/webkit/WebKit/qt/declarative/declarative.pro index 122d90a..75268f3 100644 --- a/src/3rdparty/webkit/WebKit/qt/declarative/declarative.pro +++ b/src/3rdparty/webkit/WebKit/qt/declarative/declarative.pro @@ -6,6 +6,8 @@ CONFIG += qt plugin win32|mac:!wince*:!win32-msvc:!macx-xcode:CONFIG += debug_and_release +isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../.. + QMLDIRFILE = $${_PRO_FILE_PWD_}/qmldir copy2build.input = QMLDIRFILE CONFIG(QTDIR_build) { @@ -64,13 +66,7 @@ qmldir.files += $$PWD/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH symbian:{ - load(data_caging_paths) - include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - - importFiles.sources = qmlwebkitplugin.dll qmldir - importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH - - DEPLOYMENT = importFiles + TARGET.UID3 = 0x20021321 } INSTALLS += target qmldir diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index ea60792..26e587d 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -1452,7 +1452,7 @@ qint64 QIODevicePrivate::peek(char *data, qint64 maxSize) return readBytes; buffer.ungetBlock(data, readBytes); - pos -= readBytes; + *pPos -= readBytes; return readBytes; } @@ -1467,7 +1467,7 @@ QByteArray QIODevicePrivate::peek(qint64 maxSize) return result; buffer.ungetBlock(result.constData(), result.size()); - pos -= result.size(); + *pPos -= result.size(); return result; } diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp index 9dc828d..8e8a88a 100644 --- a/src/corelib/thread/qsemaphore.cpp +++ b/src/corelib/thread/qsemaphore.cpp @@ -44,6 +44,8 @@ #ifndef QT_NO_THREAD #include "qmutex.h" #include "qwaitcondition.h" +#include "qelapsedtimer.h" +#include "qdatetime.h" QT_BEGIN_NAMESPACE @@ -218,8 +220,11 @@ bool QSemaphore::tryAcquire(int n, int timeout) while (n > d->avail) d->cond.wait(locker.mutex()); } else { + QElapsedTimer timer; + timer.start(); while (n > d->avail) { - if (!d->cond.wait(locker.mutex(), timeout)) + if (timer.hasExpired(timeout) + || !d->cond.wait(locker.mutex(), timeout - timer.elapsed())) return false; } } diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 2221d78..60e9dd3 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -660,10 +660,9 @@ void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(enginePriv->contextClass->newUrlContext(url)); - scriptContext->pushScope(enginePriv->globalClass->globalObject()); + scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject()); - QScriptValue scope = scriptEngine->newObject(); - scriptContext->setActivationObject(scope); + QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine); scriptContext->pushScope(scope); scriptEngine->evaluate(code, url, 1); @@ -686,10 +685,9 @@ void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(enginePriv->contextClass->newUrlContext(this, 0, url)); - scriptContext->pushScope(enginePriv->globalClass->globalObject()); - - QScriptValue scope = scriptEngine->newObject(); - scriptContext->setActivationObject(scope); + scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject()); + + QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine); scriptContext->pushScope(scope); scriptEngine->evaluate(code, url, 1); diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index b1aecfa..8ae5f2f 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -145,7 +145,7 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *ex if (!dd->cachedClosures.at(progIdx)) { QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(ep->contextClass->newSharedContext()); - scriptContext->pushScope(ep->globalClass->globalObject()); + scriptContext->pushScope(ep->globalClass->staticGlobalObject()); dd->cachedClosures[progIdx] = new QScriptValue(scriptEngine->evaluate(data->expression, data->url, data->line)); scriptEngine->popContext(); } @@ -188,7 +188,7 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex } else { scriptContext->pushScope(ep->contextClass->newContext(context, object)); } - scriptContext->pushScope(ep->globalClass->globalObject()); + scriptContext->pushScope(ep->globalClass->staticGlobalObject()); QScriptValue rv = ep->scriptEngine.evaluate(program, fileName, lineNumber); ep->scriptEngine.popContext(); return rv; @@ -206,7 +206,7 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex } else { scriptContext->pushScope(ep->contextClass->newContext(context, object)); } - scriptContext->pushScope(ep->globalClass->globalObject()); + scriptContext->pushScope(ep->globalClass->staticGlobalObject()); QScriptValue rv = ep->scriptEngine.evaluate(program); ep->scriptEngine.popContext(); return rv; @@ -369,7 +369,7 @@ QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool * QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); data->expressionContext = ep->contextClass->newContext(data->context(), data->me); scriptContext->pushScope(data->expressionContext); - scriptContext->pushScope(ep->globalClass->globalObject()); + scriptContext->pushScope(ep->globalClass->staticGlobalObject()); if (data->expressionRewritten) { data->expressionFunction = scriptEngine->evaluate(data->expression, diff --git a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp index 6e107fb..39ea101 100644 --- a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp @@ -41,10 +41,13 @@ #include "private/qdeclarativeglobalscriptclass_p.h" +#include <QtCore/qvector.h> #include <QtScript/qscriptstring.h> #include <QtScript/qscriptengine.h> #include <QtScript/qscriptvalueiterator.h> +#include <private/qscriptdeclarativeclass_p.h> + QT_BEGIN_NAMESPACE /* @@ -55,23 +58,31 @@ QDeclarativeGlobalScriptClass::QDeclarativeGlobalScriptClass(QScriptEngine *engi { QString eval = QLatin1String("eval"); - QScriptValue globalObject = engine->globalObject(); + QScriptValue originalGlobalObject = engine->globalObject(); - m_globalObject = engine->newObject(); QScriptValue newGlobalObject = engine->newObject(); - QScriptValueIterator iter(globalObject); - - while (iter.hasNext()) { - iter.next(); - - QString name = iter.name(); - - if (name != eval) - m_globalObject.setProperty(iter.scriptName(), iter.value()); - newGlobalObject.setProperty(iter.scriptName(), iter.value()); - - m_illegalNames.insert(name); + { + QScriptValueIterator iter(originalGlobalObject); + QVector<QString> names; + QVector<QScriptValue> values; + QVector<QScriptValue::PropertyFlags> flags; + while (iter.hasNext()) { + iter.next(); + + QString name = iter.name(); + + if (name != eval) { + names.append(name); + values.append(iter.value()); + flags.append(iter.flags() | QScriptValue::Undeletable); + } + newGlobalObject.setProperty(iter.scriptName(), iter.value()); + + m_illegalNames.insert(name); + } + m_staticGlobalObject = QScriptDeclarativeClass::newStaticScopeObject( + engine, names.size(), names.constData(), values.constData(), flags.constData()); } newGlobalObject.setScriptClass(this); diff --git a/src/declarative/qml/qdeclarativeglobalscriptclass_p.h b/src/declarative/qml/qdeclarativeglobalscriptclass_p.h index 7690edd..414bf02 100644 --- a/src/declarative/qml/qdeclarativeglobalscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeglobalscriptclass_p.h @@ -75,13 +75,13 @@ public: void explicitSetProperty(const QString &, const QScriptValue &); - const QScriptValue &globalObject() const { return m_globalObject; } + const QScriptValue &staticGlobalObject() const { return m_staticGlobalObject; } const QSet<QString> &illegalNames() const { return m_illegalNames; } private: QSet<QString> m_illegalNames; - QScriptValue m_globalObject; + QScriptValue m_staticGlobalObject; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeinclude.cpp b/src/declarative/qml/qdeclarativeinclude.cpp index c29005a..f26b54f 100644 --- a/src/declarative/qml/qdeclarativeinclude.cpp +++ b/src/declarative/qml/qdeclarativeinclude.cpp @@ -240,7 +240,7 @@ QScriptValue QDeclarativeInclude::include(QScriptContext *ctxt, QScriptEngine *e QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(engine); scriptContext->pushScope(ep->contextClass->newUrlContext(context, 0, urlString)); - scriptContext->pushScope(ep->globalClass->globalObject()); + scriptContext->pushScope(ep->globalClass->staticGlobalObject()); QScriptValue scope = QScriptDeclarativeClass::scopeChainValue(ctxt, -5); scriptContext->pushScope(scope); scriptContext->setActivationObject(scope); diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index 969acc4..fea6e8d 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -415,7 +415,10 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEg // At this point, the widget's window should be created and have the correct visual. Now we // just need to create the EGL surface for it: - return eglCreateWindowSurface(QEgl::display(), config, (EGLNativeWindowType)widget->winId(), 0); + EGLSurface surf = eglCreateWindowSurface(QEgl::display(), config, (EGLNativeWindowType)widget->winId(), 0); + if (surf == EGL_NO_SURFACE) + qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); + return surf; } if (x11PixmapData) { diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 2a85fdc..ef719ca 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3065,6 +3065,11 @@ bool QETWidget::translateMouseEvent(const MSG &msg) break; } } +#ifndef Q_OS_WINCE + static bool trackMouseEventLookup = false; + typedef BOOL (WINAPI *PtrTrackMouseEvent)(LPTRACKMOUSEEVENT); + static PtrTrackMouseEvent ptrTrackMouseEvent = 0; +#endif state = translateButtonState(msg.wParam, type, button); // button state const QPoint widgetPos = mapFromGlobal(QPoint(msg.pt.x, msg.pt.y)); QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); @@ -3129,9 +3134,6 @@ bool QETWidget::translateMouseEvent(const MSG &msg) #ifndef Q_OS_WINCE if (curWin != 0) { - static bool trackMouseEventLookup = false; - typedef BOOL (WINAPI *PtrTrackMouseEvent)(LPTRACKMOUSEEVENT); - static PtrTrackMouseEvent ptrTrackMouseEvent = 0; if (!trackMouseEventLookup) { trackMouseEventLookup = true; ptrTrackMouseEvent = (PtrTrackMouseEvent)QLibrary::resolve(QLatin1String("comctl32"), "_TrackMouseEvent"); @@ -3245,6 +3247,21 @@ bool QETWidget::translateMouseEvent(const MSG &msg) qt_button_down = 0; } +#ifndef Q_OS_WINCE + if (type == QEvent::MouseButtonPress + && QApplication::activePopupWidget() != activePopupWidget + && ptrTrackMouseEvent + && curWin) { + // Since curWin is already the window we clicked on, + // we have to setup the mouse tracking here. + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(TRACKMOUSEEVENT); + tme.dwFlags = 0x00000002; // TME_LEAVE + tme.hwndTrack = curWin; // Track on window receiving msgs + tme.dwHoverTime = (DWORD)-1; // HOVER_DEFAULT + ptrTrackMouseEvent(&tme); + } +#endif if (type == QEvent::MouseButtonPress && QApplication::activePopupWidget() != activePopupWidget && replayPopupMouseEvent) { diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp index 873b8f9..3dc6afc 100644 --- a/src/gui/kernel/qkeymapper_mac.cpp +++ b/src/gui/kernel/qkeymapper_mac.cpp @@ -866,14 +866,27 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef e UInt32 macModifiers = 0; GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0, sizeof(macModifiers), 0, &macModifiers); +#ifdef QT_MAC_USE_COCOA + // The unicode characters in the range 0xF700-0xF747 are reserved + // by Mac OS X for transient use as keyboard function keys. We + // wont send 'text' for such key events. This is done to match + // behavior on other platforms. + unsigned int *unicodeKey = (unsigned int*)info; + if (*unicodeKey >= 0xf700 && *unicodeKey <= 0xf747) + text = QString(); + bool isAccepted; +#endif handled_event = QKeyMapper::sendKeyEvent(widget, grab, (ekind == kEventRawKeyUp) ? QEvent::KeyRelease : QEvent::KeyPress, qtKey, modifiers, text, ekind == kEventRawKeyRepeat, 0, macScanCode, macVirtualKey, macModifiers #ifdef QT_MAC_USE_COCOA - ,static_cast<bool *>(info) + ,&isAccepted #endif ); +#ifdef QT_MAC_USE_COCOA + *unicodeKey = (unsigned int)isAccepted; +#endif } return handled_event; } diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 8cef03c..3fc27f4 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -682,10 +682,12 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve NSEvent *event = static_cast<NSEvent *>(keyEvent); EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef])); Q_ASSERT(key_event); + unsigned int info = 0; if ([event type] == NSKeyDown) { NSString *characters = [event characters]; unichar value = [characters characterAtIndex:0]; qt_keymapper_private()->updateKeyMap(0, key_event, (void *)&value); + info = value; } // Redirect keys to alien widgets. @@ -701,9 +703,8 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve if (mustUseCocoaKeyEvent()) return qt_dispatchKeyEventWithCocoa(keyEvent, widgetToGetEvent); - bool isAccepted; - bool consumed = qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &isAccepted, true); - return consumed && isAccepted; + bool consumed = qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &info, true); + return consumed && (info != 0); #endif } diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 280712a..a9bb691 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2804,7 +2804,7 @@ void QWidgetPrivate::setSubWindowStacking(bool set) QList<QWidget *> widgets = q->findChildren<QWidget *>(); for (int i=0; i<widgets.size(); ++i) { QWidget *child = widgets.at(i); - if (child->isWindow() && child->testAttribute(Qt::WA_WState_Created)) { + if (child->isWindow() && child->testAttribute(Qt::WA_WState_Created) && child->isVisibleTo(q)) { if (set) [qt_mac_window_for(q) addChildWindow:qt_mac_window_for(child) ordered:NSWindowAbove]; else diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 139139f..e6c36a4 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -413,7 +413,7 @@ struct QtFontFamily bool fixedPitchComputed : 1; #endif #ifdef Q_WS_X11 - bool symbol_checked; + bool symbol_checked : 1; #endif QString name; diff --git a/src/imports/folderlistmodel/folderlistmodel.pro b/src/imports/folderlistmodel/folderlistmodel.pro index dced319..49a6baa 100644 --- a/src/imports/folderlistmodel/folderlistmodel.pro +++ b/src/imports/folderlistmodel/folderlistmodel.pro @@ -14,6 +14,7 @@ qmldir.files += $$PWD/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH symbian:{ + TARGET.UID3 = 0x20021320 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) importFiles.sources = qmlfolderlistmodelplugin.dll qmldir diff --git a/src/imports/gestures/gestures.pro b/src/imports/gestures/gestures.pro index d6dc758..265bbca 100644 --- a/src/imports/gestures/gestures.pro +++ b/src/imports/gestures/gestures.pro @@ -14,6 +14,7 @@ qmldir.files += $$PWD/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH symbian:{ + TARGET.UID3 = 0x2002131F include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) importFiles.sources = qmlgesturesplugin.dll qmldir diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro index 95ec633..91c1b9f 100644 --- a/src/imports/particles/particles.pro +++ b/src/imports/particles/particles.pro @@ -18,6 +18,7 @@ qmldir.files += $$PWD/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH symbian:{ + TARGET.UID3 = 0x2002131E include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) importFiles.sources = qmlparticlesplugin.dll qmldir diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp index 2d66d9e..cd38f5e 100644 --- a/src/multimedia/video/qvideoframe.cpp +++ b/src/multimedia/video/qvideoframe.cpp @@ -665,6 +665,7 @@ QVideoFrame::PixelFormat QVideoFrame::pixelFormatFromImageFormat(QImage::Format case QImage::Format_RGB16: return Format_RGB565; case QImage::Format_ARGB8565_Premultiplied: + return Format_ARGB8565_Premultiplied; case QImage::Format_RGB666: case QImage::Format_ARGB6666_Premultiplied: return Format_Invalid; diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 36a0cc7..9bd93a2 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -574,17 +574,17 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates() } } #elif defined(Q_OS_AIX) - systemCerts.append(QSslCertificate::fromPath("/var/ssl/certs/*.pem", QSsl::Pem, QRegExp::Wildcard)); + systemCerts.append(QSslCertificate::fromPath(QLatin1String("/var/ssl/certs/*.pem"), QSsl::Pem, QRegExp::Wildcard)); #elif defined(Q_OS_SOLARIS) - systemCerts.append(QSslCertificate::fromPath("/usr/local/ssl/certs/*.pem", QSsl::Pem, QRegExp::Wildcard)); + systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/local/ssl/certs/*.pem"), QSsl::Pem, QRegExp::Wildcard)); #elif defined(Q_OS_HPUX) - systemCerts.append(QSslCertificate::fromPath("/opt/openssl/certs/*.pem", QSsl::Pem, QRegExp::Wildcard)); + systemCerts.append(QSslCertificate::fromPath(QLatin1String("/opt/openssl/certs/*.pem"), QSsl::Pem, QRegExp::Wildcard)); #elif defined(Q_OS_LINUX) - systemCerts.append(QSslCertificate::fromPath("/etc/ssl/certs/*.pem", QSsl::Pem, QRegExp::Wildcard)); // (K)ubuntu, OpenSUSE, Mandriva, ... - systemCerts.append(QSslCertificate::fromPath("/etc/pki/tls/certs/ca-bundle.crt", QSsl::Pem)); // Fedora - systemCerts.append(QSslCertificate::fromPath("/usr/lib/ssl/certs/*.pem", QSsl::Pem, QRegExp::Wildcard)); // Gentoo, Mandrake - systemCerts.append(QSslCertificate::fromPath("/usr/share/ssl/*.pem", QSsl::Pem, QRegExp::Wildcard)); // Centos, Redhat, SuSE - systemCerts.append(QSslCertificate::fromPath("/usr/local/ssl/*.pem", QSsl::Pem, QRegExp::Wildcard)); // Normal OpenSSL Tarball + systemCerts.append(QSslCertificate::fromPath(QLatin1String("/etc/ssl/certs/*.pem"), QSsl::Pem, QRegExp::Wildcard)); // (K)ubuntu, OpenSUSE, Mandriva, ... + systemCerts.append(QSslCertificate::fromPath(QLatin1String("/etc/pki/tls/certs/ca-bundle.crt"), QSsl::Pem)); // Fedora + systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/lib/ssl/certs/*.pem"), QSsl::Pem, QRegExp::Wildcard)); // Gentoo, Mandrake + systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/share/ssl/*.pem"), QSsl::Pem, QRegExp::Wildcard)); // Centos, Redhat, SuSE + systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/local/ssl/*.pem"), QSsl::Pem, QRegExp::Wildcard)); // Normal OpenSSL Tarball #endif return systemCerts; } diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 42ae98f..d3c3858 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE typedef OSStatus (*PtrSecTrustSettingsCopyCertificates)(int, CFArrayRef*); typedef OSStatus (*PtrSecTrustCopyAnchorCertificates)(CFArrayRef*); #elif defined(Q_OS_WIN) -#include <Wincrypt.h> +#include <wincrypt.h> #ifndef HCRYPTPROV_LEGACY #define HCRYPTPROV_LEGACY HCRYPTPROV #endif diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index b4c85ac..9effb34 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1521,6 +1521,32 @@ bool operator==(const QGLFormat& a, const QGLFormat& b) && a.d->profile == b.d->profile); } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug dbg, const QGLFormat &f) +{ + const QGLFormatPrivate * const d = f.d; + + dbg.nospace() << "QGLFormat(" + << "options " << d->opts + << ", plane " << d->pln + << ", depthBufferSize " << d->depthSize + << ", accumBufferSize " << d->accumSize + << ", stencilBufferSize " << d->stencilSize + << ", redBufferSize " << d->redSize + << ", greenBufferSize " << d->greenSize + << ", blueBufferSize " << d->blueSize + << ", alphaBufferSize " << d->alphaSize + << ", samples " << d->numSamples + << ", swapInterval " << d->swapInterval + << ", majorVersion " << d->majorVersion + << ", minorVersion " << d->minorVersion + << ", profile " << d->profile + << ')'; + + return dbg.space(); +} +#endif + /*! Returns false if all the options of the two QGLFormat objects diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index f0b36f7..f85cad5 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -281,6 +281,9 @@ private: friend Q_OPENGL_EXPORT bool operator==(const QGLFormat&, const QGLFormat&); friend Q_OPENGL_EXPORT bool operator!=(const QGLFormat&, const QGLFormat&); +#ifndef QT_NO_DEBUG_STREAM + friend Q_OPENGL_EXPORT QDebug operator<<(QDebug, const QGLFormat &); +#endif }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGLFormat::OpenGLVersionFlags) @@ -288,6 +291,10 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QGLFormat::OpenGLVersionFlags) Q_OPENGL_EXPORT bool operator==(const QGLFormat&, const QGLFormat&); Q_OPENGL_EXPORT bool operator!=(const QGLFormat&, const QGLFormat&); +#ifndef QT_NO_DEBUG_STREAM +Q_OPENGL_EXPORT QDebug operator<<(QDebug, const QGLFormat &); +#endif + class Q_OPENGL_EXPORT QGLContext { Q_DECLARE_PRIVATE(QGLContext) diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp index e08d135..b6e11df 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp +++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp @@ -53,16 +53,30 @@ QT_BEGIN_NAMESPACE QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine) - : CActive(CActive::EPriorityUserInput), engine(engine), - ipConnectionNotifier(0), iHandleStateNotificationsFromManager(false), - iFirstSync(true), iStoppedByUser(false), iClosedByUser(false), iDeprecatedConnectionId(0), - iError(QNetworkSession::UnknownSessionError), iALREnabled(0), iConnectInBackground(false) +: CActive(CActive::EPriorityUserInput), engine(engine), + iDynamicUnSetdefaultif(0), ipConnectionNotifier(0), + iHandleStateNotificationsFromManager(false), iFirstSync(true), iStoppedByUser(false), + iClosedByUser(false), iError(QNetworkSession::UnknownSessionError), iALREnabled(0), + iConnectInBackground(false), isOpening(false) { CActiveScheduler::Add(this); #ifdef SNAP_FUNCTIONALITY_AVAILABLE iMobility = NULL; #endif + // Try to load "Open C" dll dynamically and + // try to attach to unsetdefaultif function dynamically. + // This is to avoid build breaks with old OpenC versions. + if (iOpenCLibrary.Load(_L("libc")) == KErrNone) { + iDynamicUnSetdefaultif = (TOpenCUnSetdefaultifFunction)iOpenCLibrary.Lookup(597); + } +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNS this : " << QString::number((uint)this) << " - "; + if (iDynamicUnSetdefaultif) + qDebug() << "dynamic unsetdefaultif() is present in PIPS library. "; + else + qDebug() << "dynamic unsetdefaultif() not present in PIPS library. "; +#endif TRAP_IGNORE(iConnectionMonitor.ConnectL()); } @@ -70,6 +84,7 @@ QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine) QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl() { isOpen = false; + isOpening = false; // Cancel Connection Progress Notifications first. // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start() @@ -77,9 +92,6 @@ QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl() delete ipConnectionNotifier; ipConnectionNotifier = NULL; - // Cancel possible RConnection::Start() - Cancel(); - #ifdef SNAP_FUNCTIONALITY_AVAILABLE if (iMobility) { delete iMobility; @@ -87,13 +99,19 @@ QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl() } #endif - iConnection.Close(); + // Cancel possible RConnection::Start() + Cancel(); iSocketServ.Close(); // Close global 'Open C' RConnection + // Clears also possible unsetdefaultif() flags. setdefaultif(0); iConnectionMonitor.Close(); + iOpenCLibrary.Close(); +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNS this : " << QString::number((uint)this) << " - destroyed (and setdefaultif(0))"; +#endif } void QNetworkSessionPrivateImpl::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState) @@ -101,18 +119,12 @@ void QNetworkSessionPrivateImpl::configurationStateChanged(TUint32 accessPointId if (iHandleStateNotificationsFromManager) { #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG qDebug() << "QNS this : " << QString::number((uint)this) << " - " - << "configurationStateChanged from manager for IAP : " << QString::number(accessPointId) - << "configurationStateChanged connMon ID : " << QString::number(connMonId) - << " : to a state: " << newState - << " whereas my current state is: " << state; -#endif - if (connMonId == iDeprecatedConnectionId) { -#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG - qDebug() << "QNS this : " << QString::number((uint)this) << " - " - << "however status update from manager ignored because it related to already closed connection."; + << "configurationStateChanged from manager for IAP : " << QString::number(accessPointId) + << "connMon ID : " << QString::number(connMonId) << " : to a state: " << newState + << "whereas my current state is: " << state; +#else + Q_UNUSED(connMonId); #endif - return; - } this->newState(newState, accessPointId); } } @@ -236,6 +248,14 @@ QNetworkInterface QNetworkSessionPrivateImpl::interface(TUint iapId) const #ifndef QT_NO_NETWORKINTERFACE QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const { +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNS this : " << QString::number((uint)this) << " - " + << "currentInterface() requested, state: " << state + << "publicConfig validity: " << publicConfig.isValid(); + if (activeInterface.isValid()) + qDebug() << "interface is: " << activeInterface.humanReadableName(); +#endif + if (!publicConfig.isValid() || state != QNetworkSession::Connected) { return QNetworkInterface(); } @@ -292,12 +312,14 @@ void QNetworkSessionPrivateImpl::open() #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "open() called, session state is: " << state << " and isOpen is: " - << isOpen; + << isOpen << isOpening; #endif - if (isOpen || (state == QNetworkSession::Connecting)) { + + if (isOpen || isOpening) return; - } - + + isOpening = true; + // Stop handling IAP state change signals from QNetworkConfigurationManagerPrivate // => RConnection::ProgressNotification will be used for IAP/SNAP monitoring iHandleStateNotificationsFromManager = false; @@ -325,7 +347,6 @@ void QNetworkSessionPrivateImpl::open() // Clear possible previous states iStoppedByUser = false; iClosedByUser = false; - iDeprecatedConnectionId = 0; TInt error = iSocketServ.Connect(); if (error != KErrNone) { @@ -358,44 +379,6 @@ void QNetworkSessionPrivateImpl::open() } if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { - // Search through existing connections. - // If there is already connection which matches to given IAP - // try to attach to existing connection. - TBool connected(EFalse); - TConnectionInfoBuf connInfo; - TUint count; - if (iConnection.EnumerateConnections(count) == KErrNone) { - for (TUint i=1; i<=count; i++) { - // Note: GetConnectionInfo expects 1-based index. - if (iConnection.GetConnectionInfo(i, connInfo) == KErrNone) { - SymbianNetworkConfigurationPrivate *symbianConfig = - toSymbianConfig(privateConfiguration(publicConfig)); - - if (connInfo().iIapId == symbianConfig->numericIdentifier()) { - if (iConnection.Attach(connInfo, RConnection::EAttachTypeNormal) == KErrNone) { - activeConfig = publicConfig; -#ifndef QT_NO_NETWORKINTERFACE - activeInterface = interface(symbianConfig->numericIdentifier()); -#endif - connected = ETrue; - startTime = QDateTime::currentDateTime(); - // Use name of the IAP to open global 'Open C' RConnection - QByteArray nameAsByteArray = publicConfig.name().toUtf8(); - ifreq ifr; - memset(&ifr, 0, sizeof(struct ifreq)); - strcpy(ifr.ifr_name, nameAsByteArray.constData()); - error = setdefaultif(&ifr); - isOpen = true; - // Make sure that state will be Connected - newState(QNetworkSession::Connected); - emit quitPendingWaitsForOpened(); - break; - } - } - } - } - } - if (!connected) { SymbianNetworkConfigurationPrivate *symbianConfig = toSymbianConfig(privateConfiguration(publicConfig)); @@ -420,13 +403,20 @@ void QNetworkSessionPrivateImpl::open() if (!IsActive()) { SetActive(); } - newState(QNetworkSession::Connecting); - } + // Avoid flip flop of states if the configuration is already + // active. IsOpen/opened() will indicate when ready. + if (state != QNetworkSession::Connected) { + newState(QNetworkSession::Connecting); + } } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { SymbianNetworkConfigurationPrivate *symbianConfig = toSymbianConfig(privateConfiguration(publicConfig)); #ifdef OCC_FUNCTIONALITY_AVAILABLE + // On Symbian^3 if service network is not reachable, it triggers a UI (aka EasyWLAN) where + // user can create new IAPs. To detect this, we need to store the number of IAPs + // there was before connection was started. + iKnownConfigsBeforeConnectionStart = engine->accessPointConfigurationIdentifiers(); TConnPrefList snapPref; TExtendedConnPref prefs; prefs.SetSnapId(symbianConfig->numericIdentifier()); @@ -441,7 +431,11 @@ void QNetworkSessionPrivateImpl::open() if (!IsActive()) { SetActive(); } - newState(QNetworkSession::Connecting); + // Avoid flip flop of states if the configuration is already + // active. IsOpen/opened() will indicate when ready. + if (state != QNetworkSession::Connected) { + newState(QNetworkSession::Connecting); + } } else if (publicConfig.type() == QNetworkConfiguration::UserChoice) { iKnownConfigsBeforeConnectionStart = engine->accessPointConfigurationIdentifiers(); iConnection.Start(iStatus); @@ -453,6 +447,7 @@ void QNetworkSessionPrivateImpl::open() if (error != KErrNone) { isOpen = false; + isOpening = false; iError = QNetworkSession::UnknownSessionError; emit QNetworkSessionPrivate::error(iError); if (ipConnectionNotifier) { @@ -496,19 +491,19 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals) << "close() called, session state is: " << state << " and isOpen is : " << isOpen; #endif - if (!isOpen) { + + if (!isOpen && state != QNetworkSession::Connecting) { return; } // Mark this session as closed-by-user so that we are able to report // distinguish between stop() and close() state transitions // when reporting. iClosedByUser = true; - isOpen = false; - activeConfig = QNetworkConfiguration(); + isOpening = false; + serviceConfig = QNetworkConfiguration(); - Cancel(); #ifdef SNAP_FUNCTIONALITY_AVAILABLE if (iMobility) { delete iMobility; @@ -522,17 +517,33 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals) iHandleStateNotificationsFromManager = true; } - iConnection.Close(); + Cancel(); // closes iConnection iSocketServ.Close(); - // Close global 'Open C' RConnection - setdefaultif(0); + // Close global 'Open C' RConnection. If OpenC supports, + // close the defaultif for good to avoid difficult timing + // and bouncing issues of network going immediately back up + // because of e.g. select() thread etc. + if (iDynamicUnSetdefaultif) { + iDynamicUnSetdefaultif(); + } else { + setdefaultif(0); + } - if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + // If UserChoice, go down immediately. If some other configuration, + // go down immediately if there is no reports expected from the platform; + // in practice Connection Monitor is aware of connections only after + // KFinishedSelection event, and hence reports only after that event, but + // that does not seem to be trusted on all Symbian versions --> safest + // to go down. + if (publicConfig.type() == QNetworkConfiguration::UserChoice || state == QNetworkSession::Connecting) { +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNS this : " << QString::number((uint)this) << " - " + << "going disconnected right away, since either UserChoice or Connecting"; +#endif newState(QNetworkSession::Closing); newState(QNetworkSession::Disconnected); } - if (allowSignals) { emit closed(); } @@ -593,6 +604,7 @@ void QNetworkSessionPrivateImpl::stop() #endif // Since we are open, use RConnection to stop the interface isOpen = false; + isOpening = false; iStoppedByUser = true; newState(QNetworkSession::Closing); if (ipConnectionNotifier) { @@ -602,6 +614,7 @@ void QNetworkSessionPrivateImpl::stop() } iConnection.Stop(RConnection::EStopAuthoritative); isOpen = true; + isOpening = false; close(false); emit closed(); } @@ -611,8 +624,13 @@ void QNetworkSessionPrivateImpl::migrate() { #ifdef SNAP_FUNCTIONALITY_AVAILABLE if (iMobility) { - // Close global 'Open C' RConnection - setdefaultif(0); + // Close global 'Open C' RConnection. If openC supports, use the 'heavy' + // version to block all subsequent requests. + if (iDynamicUnSetdefaultif) { + iDynamicUnSetdefaultif(); + } else { + setdefaultif(0); + } // Start migrating to new IAP iMobility->MigrateToPreferredCarrier(); } @@ -694,8 +712,17 @@ void QNetworkSessionPrivateImpl::PreferredCarrierAvailable(TAccessPointInfo aOld SymbianNetworkConfigurationPrivate *symbianConfig = toSymbianConfig(privateConfiguration(configs[i])); - if (symbianConfig->numericIdentifier() == aNewAPInfo.AccessPoint()) - emit preferredConfigurationChanged(configs[i], aIsSeamless); + if (symbianConfig->numericIdentifier() == aNewAPInfo.AccessPoint()) { + // Any slot connected to the signal might throw an std::exception, + // which must not propagate into Symbian code (this function is a callback + // from platform). We could convert exception to a symbian Leave, but since the + // prototype of this function bans this (no trailing 'L'), we just catch + // and drop. + QT_TRY { + emit preferredConfigurationChanged(configs[i], aIsSeamless); + } + QT_CATCH (std::exception&) {} + } } } else { migrate(); @@ -705,7 +732,10 @@ void QNetworkSessionPrivateImpl::PreferredCarrierAvailable(TAccessPointInfo aOld void QNetworkSessionPrivateImpl::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*/, TBool /*aIsSeamless*/) { if (iALREnabled > 0) { - emit newConfigurationActivated(); + QT_TRY { + emit newConfigurationActivated(); + } + QT_CATCH (std::exception&) {} } else { accept(); } @@ -715,10 +745,11 @@ void QNetworkSessionPrivateImpl::Error(TInt /*aError*/) { #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG qDebug() << "QNS this : " << QString::number((uint)this) << " - " - << "roaming Error() occured"; + << "roaming Error() occured, isOpen is: " << isOpen; #endif if (isOpen) { isOpen = false; + isOpening = false; activeConfig = QNetworkConfiguration(); serviceConfig = QNetworkConfiguration(); iError = QNetworkSession::RoamingError; @@ -727,18 +758,24 @@ void QNetworkSessionPrivateImpl::Error(TInt /*aError*/) if (ipConnectionNotifier) { ipConnectionNotifier->StopNotifications(); } - syncStateWithInterface(); - // In some cases IAP is still in Connected state when - // syncStateWithInterface(); is called - // => Following call makes sure that Session state - // changes immediately to Disconnected. - newState(QNetworkSession::Disconnected); - emit closed(); + QT_TRY { + syncStateWithInterface(); + // In some cases IAP is still in Connected state when + // syncStateWithInterface(); is called + // => Following call makes sure that Session state + // changes immediately to Disconnected. + newState(QNetworkSession::Disconnected); + emit closed(); + } + QT_CATCH (std::exception&) {} } else if (iStoppedByUser) { // If the user of this session has called the stop() and // configuration is based on internet SNAP, this needs to be // done here because platform might roam. - newState(QNetworkSession::Disconnected); + QT_TRY { + newState(QNetworkSession::Disconnected); + } + QT_CATCH (std::exception&) {} } } #endif @@ -870,7 +907,7 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia _LIT(KSetting, "IAP\\Id"); iConnection.GetIntSetting(KSetting, iapId); } - + #ifdef SNAP_FUNCTIONALITY_AVAILABLE if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { // Try to search IAP from the used SNAP using IAP Id @@ -892,8 +929,8 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia // <=> Note: It's possible that in this case reported IAP is // clone of the one of the IAPs of the used SNAP // => If mappingName matches, clone has been found - QNetworkConfiguration pt = QNetworkConfigurationManager() - .configurationFromIdentifier(QString::number(qHash(iapId))); + QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier( + QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId))); SymbianNetworkConfigurationPrivate *symbianConfig = toSymbianConfig(privateConfiguration(pt)); @@ -907,20 +944,58 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia } } } else { +#ifdef OCC_FUNCTIONALITY_AVAILABLE + // On Symbian^3 (only, not earlier or Symbian^4) if the SNAP was not reachable, it triggers + // user choice type of activity (EasyWLAN). As a result, a new IAP may be created, and + // hence if was not found yet. Therefore update configurations and see if there is something new. + // 1. Update knowledge from the databases. + engine->requestUpdate(); + // 2. Check if new configuration was created during connection creation + QList<QString> knownConfigs = engine->accessPointConfigurationIdentifiers(); +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNS this : " << QString::number((uint)this) << " - " + << "opened configuration was not known beforehand, looking for new."; +#endif + if (knownConfigs.count() > iKnownConfigsBeforeConnectionStart.count()) { + // Configuration count increased => new configuration was created + // => Search new, created configuration + QString newIapId; + for (int i=0; i < iKnownConfigsBeforeConnectionStart.count(); i++) { + if (knownConfigs[i] != iKnownConfigsBeforeConnectionStart[i]) { + newIapId = knownConfigs[i]; + break; + } + } + if (newIapId.isEmpty()) { + newIapId = knownConfigs[knownConfigs.count()-1]; + } + pt = QNetworkConfigurationManager().configurationFromIdentifier(newIapId); + if (pt.isValid()) { +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNS this : " << QString::number((uint)this) << " - " + << "new configuration was found, name, IAP id: " << pt.name() << pt.identifier(); +#endif + return pt; + } + } +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNS this : " << QString::number((uint)this) << " - " + << "configuration was not found, returning invalid."; +#endif +#endif // OCC_FUNCTIONALITY_AVAILABLE // Given IAP Id was not found from known IAPs array return QNetworkConfiguration(); } - // Matching IAP was not found from used SNAP // => IAP from another SNAP is returned // (Note: Returned IAP matches to given IAP Id) return pt; } #endif - if (publicConfig.type() == QNetworkConfiguration::UserChoice) { if (engine) { - QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier(QString::number(qHash(iapId))); + QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier( + QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId))); // Try to found User Selected IAP from known IAPs (accessPointConfigurations) if (pt.isValid()) { return pt; @@ -957,6 +1032,10 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia void QNetworkSessionPrivateImpl::RunL() { +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNS this : " << QString::number((uint)this) << " - " + << "RConnection::RunL with status code: " << iStatus.Int(); +#endif TInt statusCode = iStatus.Int(); switch (statusCode) { @@ -977,13 +1056,14 @@ void QNetworkSessionPrivateImpl::RunL() if (error != KErrNone) { isOpen = false; + isOpening = false; iError = QNetworkSession::UnknownSessionError; - emit QNetworkSessionPrivate::error(iError); + QT_TRYCATCH_LEAVING(emit QNetworkSessionPrivate::error(iError)); Cancel(); if (ipConnectionNotifier) { ipConnectionNotifier->StopNotifications(); } - syncStateWithInterface(); + QT_TRYCATCH_LEAVING(syncStateWithInterface()); return; } @@ -995,6 +1075,7 @@ void QNetworkSessionPrivateImpl::RunL() #endif isOpen = true; + isOpening = false; activeConfig = newActiveConfig; SymbianNetworkConfigurationPrivate *symbianConfig = @@ -1010,26 +1091,30 @@ void QNetworkSessionPrivateImpl::RunL() startTime = QDateTime::currentDateTime(); - newState(QNetworkSession::Connected); - emit quitPendingWaitsForOpened(); + QT_TRYCATCH_LEAVING({ + newState(QNetworkSession::Connected); + emit quitPendingWaitsForOpened(); + }); } break; case KErrNotFound: // Connection failed isOpen = false; + isOpening = false; activeConfig = QNetworkConfiguration(); serviceConfig = QNetworkConfiguration(); iError = QNetworkSession::InvalidConfigurationError; - emit QNetworkSessionPrivate::error(iError); + QT_TRYCATCH_LEAVING(emit QNetworkSessionPrivate::error(iError)); Cancel(); if (ipConnectionNotifier) { ipConnectionNotifier->StopNotifications(); } - syncStateWithInterface(); + QT_TRYCATCH_LEAVING(syncStateWithInterface()); break; case KErrCancel: // Connection attempt cancelled case KErrAlreadyExists: // Connection already exists default: isOpen = false; + isOpening = false; activeConfig = QNetworkConfiguration(); serviceConfig = QNetworkConfiguration(); if (publicConfig.state() == QNetworkConfiguration::Undefined || @@ -1038,12 +1123,12 @@ void QNetworkSessionPrivateImpl::RunL() } else { iError = QNetworkSession::UnknownSessionError; } - emit QNetworkSessionPrivate::error(iError); + QT_TRYCATCH_LEAVING(emit QNetworkSessionPrivate::error(iError)); Cancel(); if (ipConnectionNotifier) { ipConnectionNotifier->StopNotifications(); } - syncStateWithInterface(); + QT_TRYCATCH_LEAVING(syncStateWithInterface()); break; } } @@ -1110,6 +1195,12 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint return false; } + // Make sure that some lagging 'connecting' state-changes do not overwrite + // if we are already connected (may righfully still happen with roaming though). + if (state == QNetworkSession::Connected && newState == QNetworkSession::Connecting) { + return false; + } + bool emitSessionClosed = false; // If we abruptly go down and user hasn't closed the session, we've been aborted. @@ -1123,6 +1214,7 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint // application or session stops connection or when network drops // unexpectedly). isOpen = false; + isOpening = false; activeConfig = QNetworkConfiguration(); serviceConfig = QNetworkConfiguration(); iError = QNetworkSession::SessionAbortedError; @@ -1187,7 +1279,7 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint QNetworkConfiguration config = bestConfigFromSNAP(publicConfig); if ((config.state() == QNetworkConfiguration::Defined) || (config.state() == QNetworkConfiguration::Discovered)) { - + activeConfig = QNetworkConfiguration(); state = newState; #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed E to: " << state; @@ -1208,24 +1300,30 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint } } } +#ifdef OCC_FUNCTIONALITY_AVAILABLE + // If the retVal is not true here, it means that the status update may apply to an IAP outside of + // SNAP (session is based on SNAP but follows IAP outside of it), which may occur on Symbian^3 EasyWlan. + if (retVal == false && activeConfig.d.data() && activeConfig.d.data()->numericId == accessPointId) { +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed G to: " << state; +#endif + if (newState == QNetworkSession::Disconnected) { + activeConfig = QNetworkConfiguration(); + } + state = newState; + emit q->stateChanged(state); + retVal = true; + } +#endif } } - if (emitSessionClosed) { emit closed(); } if (state == QNetworkSession::Disconnected) { - // The connection has gone down, and processing of status updates must be - // stopped. Depending on platform, there may come 'connecting/connected' states - // considerably later (almost a second). Connection id is an increasing - // number, so this does not affect next _real_ 'conneting/connected' states. - - SymbianNetworkConfigurationPrivate *symbianConfig = - toSymbianConfig(privateConfiguration(publicConfig)); - - iDeprecatedConnectionId = symbianConfig->connectionIdentifier(); + // Just in case clear activeConfiguration. + activeConfig = QNetworkConfiguration(); } - return retVal; } @@ -1250,7 +1348,6 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne case KFinishedSelection: if (aError == KErrNone) { - // The user successfully selected an IAP to be used break; } else @@ -1364,7 +1461,7 @@ void ConnectionProgressNotifier::DoCancel() void ConnectionProgressNotifier::RunL() { if (iStatus == KErrNone) { - iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError); + QT_TRYCATCH_LEAVING(iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError)); SetActive(); iConnection.ProgressNotification(iProgress, iStatus); diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h index b045ff1..0754ace 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.h +++ b/src/plugins/bearer/symbian/qnetworksession_impl.h @@ -73,6 +73,8 @@ QT_BEGIN_NAMESPACE class ConnectionProgressNotifier; class SymbianEngine; +typedef void (*TOpenCUnSetdefaultifFunction)(); + class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive #ifdef SNAP_FUNCTIONALITY_AVAILABLE , public MMobilityProtocolResp @@ -153,6 +155,9 @@ private: // data QDateTime startTime; + RLibrary iOpenCLibrary; + TOpenCUnSetdefaultifFunction iDynamicUnSetdefaultif; + mutable RSocketServ iSocketServ; mutable RConnection iConnection; mutable RConnectionMonitor iConnectionMonitor; @@ -162,7 +167,6 @@ private: // data bool iFirstSync; bool iStoppedByUser; bool iClosedByUser; - TUint32 iDeprecatedConnectionId; #ifdef SNAP_FUNCTIONALITY_AVAILABLE CActiveCommsMobilityApiExt* iMobility; @@ -178,6 +182,8 @@ private: // data TUint32 iOldRoamingIap; TUint32 iNewRoamingIap; + bool isOpening; + friend class ConnectionProgressNotifier; }; diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp index ab1ba28..ca444c1 100644 --- a/src/plugins/bearer/symbian/symbianengine.cpp +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -46,7 +46,6 @@ #include <cdbcols.h> #include <d32dbms.h> #include <nifvar.h> -#include <QEventLoop> #include <QTimer> #include <QTime> // For randgen seeding #include <QtCore> // For randgen seeding @@ -73,9 +72,6 @@ QT_BEGIN_NAMESPACE -#ifdef SNAP_FUNCTIONALITY_AVAILABLE - static const int KValueThatWillBeAddedToSNAPId = 1000; -#endif static const int KUserChoiceIAPId = 0; SymbianNetworkConfigurationPrivate::SymbianNetworkConfigurationPrivate() @@ -114,8 +110,8 @@ QString SymbianNetworkConfigurationPrivate::bearerName() const } SymbianEngine::SymbianEngine(QObject *parent) -: QBearerEngine(parent), CActive(CActive::EPriorityIdle), iFirstUpdate(true), iInitOk(true), - iIgnoringUpdates(false) +: QBearerEngine(parent), CActive(CActive::EPriorityHigh), iFirstUpdate(true), iInitOk(true), + iUpdatePending(false) { } @@ -135,6 +131,9 @@ void SymbianEngine::initialize() } TRAP_IGNORE(iConnectionMonitor.ConnectL()); +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + TRAP_IGNORE(iConnectionMonitor.SetUintAttribute(EBearerIdAll, 0, KBearerGroupThreshold, 1)); +#endif TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this)); #ifdef SNAP_FUNCTIONALITY_AVAILABLE @@ -190,6 +189,28 @@ SymbianEngine::~SymbianEngine() delete cleanup; } +void SymbianEngine::delayedConfigurationUpdate() +{ + QMutexLocker locker(&mutex); + + if (iUpdatePending) { +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug("QNCM delayed configuration update (ECommit or ERecover occurred)."); +#endif + TRAPD(error, updateConfigurationsL()); + if (error == KErrNone) { + updateStatesToSnaps(); + } + iUpdatePending = false; + // Start monitoring again. + if (!IsActive()) { + SetActive(); + // Start waiting for new notification + ipCommsDB->RequestNotification(iStatus); + } + } +} + bool SymbianEngine::hasIdentifier(const QString &id) { QMutexLocker locker(&mutex); @@ -261,7 +282,7 @@ void SymbianEngine::updateConfigurationsL() RCmConnectionMethod connectionMethod = iCmManager.ConnectionMethodL(connectionMethods[i]); CleanupClosePushL(connectionMethod); TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); - QString ident = QString::number(qHash(iapId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId)); if (accessPointConfigurations.contains(ident)) { knownConfigs.removeOne(ident); } else { @@ -272,7 +293,11 @@ void SymbianEngine::updateConfigurationsL() accessPointConfigurations.insert(ptr->id, ptr); mutex.unlock(); - emit configurationAdded(ptr); + // Emit configuration added. Connected slots may throw execptions + // which propagate here --> must be converted to leaves (standard + // std::exception would cause any TRAP trapping this function to terminate + // program). + QT_TRYCATCH_LEAVING(emit configurationAdded(ptr)); mutex.lock(); } } @@ -288,15 +313,15 @@ void SymbianEngine::updateConfigurationsL() RCmDestination destination; destination = iCmManager.DestinationL(destinations[i]); CleanupClosePushL(destination); - QString ident = QString::number(qHash(destination.Id()+KValueThatWillBeAddedToSNAPId)); //TODO: Check if it's ok to add 1000 SNAP Id to prevent SNAP ids overlapping IAP ids + QString ident = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX + + QString::number(qHash(destination.Id())); if (snapConfigurations.contains(ident)) { knownSnapConfigs.removeOne(ident); } else { SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate; - CleanupStack::PushL(cpPriv); HBufC *pName = destination.NameLC(); - cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()); + QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length())); CleanupStack::PopAndDestroy(pName); pName = NULL; @@ -313,10 +338,8 @@ void SymbianEngine::updateConfigurationsL() snapConfigurations.insert(ident, ptr); mutex.unlock(); - emit configurationAdded(ptr); + QT_TRYCATCH_LEAVING(emit configurationAdded(ptr)); mutex.lock(); - - CleanupStack::Pop(cpPriv); } QNetworkConfigurationPrivatePointer privSNAP = snapConfigurations.value(ident); @@ -325,7 +348,7 @@ void SymbianEngine::updateConfigurationsL() CleanupClosePushL(connectionMethod); TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); - QString iface = QString::number(qHash(iapId)); + QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId)); // Check that IAP can be found from accessPointConfigurations list QNetworkConfigurationPrivatePointer priv = accessPointConfigurations.value(iface); if (!priv) { @@ -336,7 +359,7 @@ void SymbianEngine::updateConfigurationsL() accessPointConfigurations.insert(ptr->id, ptr); mutex.unlock(); - emit configurationAdded(ptr); + QT_TRYCATCH_LEAVING(emit configurationAdded(ptr)); mutex.lock(); QMutexLocker configLocker(&privSNAP->mutex); @@ -380,7 +403,7 @@ void SymbianEngine::updateConfigurationsL() TInt retVal = pDbTView->GotoFirstRecord(); while (retVal == KErrNone) { pDbTView->ReadUintL(TPtrC(COMMDB_ID), apId); - QString ident = QString::number(qHash(apId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); if (accessPointConfigurations.contains(ident)) { knownConfigs.removeOne(ident); } else { @@ -390,7 +413,7 @@ void SymbianEngine::updateConfigurationsL() accessPointConfigurations.insert(ident, ptr); mutex.unlock(); - emit configurationAdded(ptr); + QT_TRYCATCH_LEAVING(emit configurationAdded(ptr)); mutex.lock(); } else { delete cpPriv; @@ -400,7 +423,7 @@ void SymbianEngine::updateConfigurationsL() } CleanupStack::PopAndDestroy(pDbTView); #endif - updateActiveAccessPoints(); + QT_TRYCATCH_LEAVING(updateActiveAccessPoints()); foreach (const QString &oldIface, knownConfigs) { //remove non existing IAP @@ -408,6 +431,7 @@ void SymbianEngine::updateConfigurationsL() mutex.unlock(); emit configurationRemoved(ptr); + QT_TRYCATCH_LEAVING(emit configurationRemoved(ptr)); mutex.lock(); // Remove non existing IAP from SNAPs @@ -431,6 +455,7 @@ void SymbianEngine::updateConfigurationsL() mutex.unlock(); emit configurationRemoved(ptr); + QT_TRYCATCH_LEAVING(emit configurationRemoved(ptr)); mutex.lock(); } @@ -445,14 +470,12 @@ SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL( RCmConnectionMethod& connectionMethod) { SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate; - CleanupStack::PushL(cpPriv); - TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); - QString ident = QString::number(qHash(iapId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId)); HBufC *pName = connectionMethod.GetStringAttributeL(CMManager::ECmName); CleanupStack::PushL(pName); - cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()); + QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length())); CleanupStack::PopAndDestroy(pName); pName = NULL; @@ -500,7 +523,7 @@ SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL( if (error == KErrNone && pName) { CleanupStack::PushL(pName); - cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length()); + QT_TRYCATCH_LEAVING(cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length())); CleanupStack::PopAndDestroy(pName); pName = NULL; } @@ -518,8 +541,6 @@ SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL( cpPriv->type = QNetworkConfiguration::InternetAccessPoint; cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; cpPriv->roamingSupported = false; - - CleanupStack::Pop(cpPriv); return cpPriv; } #else @@ -550,9 +571,9 @@ void SymbianEngine::readNetworkConfigurationValuesFromCommsDbL( User::Leave(KErrNotFound); } - QString ident = QString::number(qHash(aApId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(aApId)); - apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length()); + QT_TRYCATCH_LEAVING(apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length())); apNetworkConfiguration->isValid = true; apNetworkConfiguration->id = ident; apNetworkConfiguration->numericId = aApId; @@ -617,10 +638,12 @@ QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfigurationL() TCmDefConnValue defaultConnectionValue; iCmManager.ReadDefConnL(defaultConnectionValue); if (defaultConnectionValue.iType == ECmDefConnDestination) { - QString iface = QString::number(qHash(defaultConnectionValue.iId+KValueThatWillBeAddedToSNAPId)); + QString iface = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX + + QString::number(qHash(defaultConnectionValue.iId)); ptr = snapConfigurations.value(iface); } else if (defaultConnectionValue.iType == ECmDefConnConnectionMethod) { - QString iface = QString::number(qHash(defaultConnectionValue.iId)); + QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX + + QString::number(qHash(defaultConnectionValue.iId)); ptr = accessPointConfigurations.value(iface); } #endif @@ -658,8 +681,14 @@ void SymbianEngine::updateActiveAccessPoints() iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount); iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); User::WaitForRequest(status); - QString ident = QString::number(qHash(apId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); +#ifdef OCC_FUNCTIONALITY_AVAILABLE + if (!ptr) { + // If IAP was not found, check if the update was about EasyWLAN + ptr = configurationFromEasyWlan(apId, connectionId); + } +#endif if (ptr) { iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status); User::WaitForRequest(status); @@ -690,7 +719,7 @@ void SymbianEngine::updateActiveAccessPoints() if (iOnline != online) { iOnline = online; mutex.unlock(); - emit this->onlineStateChanged(iOnline); + emit this->onlineStateChanged(online); mutex.lock(); } } @@ -715,7 +744,8 @@ void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapIn // Set state of returned IAPs to Discovered // if state is not already Active for(TUint i=0; i<iapInfo.iCount; i++) { - QString ident = QString::number(qHash(iapInfo.iIap[i].iIapId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX + + QString::number(qHash(iapInfo.iIap[i].iIapId)); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); if (ptr) { unavailableConfigs.removeOne(ident); @@ -783,6 +813,59 @@ void SymbianEngine::updateStatesToSnaps() } } +#ifdef SNAP_FUNCTIONALITY_AVAILABLE +void SymbianEngine::updateMobileBearerToConfigs(TConnMonBearerInfo bearerInfo) +{ + QHash<QString, QNetworkConfigurationPrivatePointer>::const_iterator i = + accessPointConfigurations.constBegin(); + while (i != accessPointConfigurations.constEnd()) { + QNetworkConfigurationPrivatePointer ptr = i.value(); + + QMutexLocker locker(&ptr->mutex); + + SymbianNetworkConfigurationPrivate *p = toSymbianConfig(ptr); + + if (p->bearer >= SymbianNetworkConfigurationPrivate::Bearer2G && + p->bearer <= SymbianNetworkConfigurationPrivate::BearerHSPA) { + switch (bearerInfo) { + case EBearerInfoCSD: + p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G; + break; + case EBearerInfoWCDMA: + p->bearer = SymbianNetworkConfigurationPrivate::BearerWCDMA; + break; + case EBearerInfoCDMA2000: + p->bearer = SymbianNetworkConfigurationPrivate::BearerCDMA2000; + break; + case EBearerInfoGPRS: + p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G; + break; + case EBearerInfoHSCSD: + p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G; + break; + case EBearerInfoEdgeGPRS: + p->bearer = SymbianNetworkConfigurationPrivate::Bearer2G; + break; + case EBearerInfoWcdmaCSD: + p->bearer = SymbianNetworkConfigurationPrivate::BearerWCDMA; + break; + case EBearerInfoHSDPA: + p->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA; + break; + case EBearerInfoHSUPA: + p->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA; + break; + case EBearerInfoHSxPA: + p->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA; + break; + } + } + + ++i; + } +} +#endif + bool SymbianEngine::changeConfigurationStateTo(QNetworkConfigurationPrivatePointer ptr, QNetworkConfiguration::StateFlags newState) { @@ -873,55 +956,30 @@ void SymbianEngine::RunL() { QMutexLocker locker(&mutex); - if (iIgnoringUpdates) { -#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG - qDebug("QNCM CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently)."); -#endif - return; - } - - RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); - - switch (event) { - case RDbNotifier::EUnlock: /** All read locks have been removed. */ - case RDbNotifier::ECommit: /** A transaction has been committed. */ - case RDbNotifier::ERollback: /** A transaction has been rolled back */ - case RDbNotifier::ERecover: /** The database has been recovered */ + if (iStatus != KErrCancel) { + // By default, start relistening notifications. Stop only if interesting event occured. + iWaitingCommsDatabaseNotifications = true; + RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); + switch (event) { + case RDbNotifier::ECommit: /** A transaction has been committed. */ + case RDbNotifier::ERecover: /** The database has been recovered */ #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG - qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int()); + qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int()); #endif - iIgnoringUpdates = true; - // Other events than ECommit get lower priority. In practice with those events, - // we delay_before_updating methods, whereas - // with ECommit we _update_before_delaying the reaction to next event. - // Few important notes: 1) listening to only ECommit does not seem to be adequate, - // but updates will be missed. Hence other events are reacted upon too. - // 2) RDbNotifier records the most significant event, and that will be returned once - // we issue new RequestNotification, and hence updates will not be missed even - // when we are 'not reacting to them' for few seconds. - if (event == RDbNotifier::ECommit) { - TRAPD(error, updateConfigurationsL()); - if (error == KErrNone) { - updateStatesToSnaps(); - } - locker.unlock(); - waitRandomTime(); - locker.relock(); - } else { - locker.unlock(); - waitRandomTime(); - locker.relock(); - TRAPD(error, updateConfigurationsL()); - if (error == KErrNone) { - updateStatesToSnaps(); + // Mark that there is update pending. No need to ask more events, + // as we know we will be updating anyway when the timer expires. + if (!iUpdatePending) { + iUpdatePending = true; + iWaitingCommsDatabaseNotifications = false; + // Update after random time, so that many processes won't + // start updating simultaneously + updateConfigurationsAfterRandomTime(); } + break; + default: + // Do nothing + break; } - iIgnoringUpdates = false; // Wait time done, allow updating again - iWaitingCommsDatabaseNotifications = true; - break; - default: - // Do nothing - break; } if (iWaitingCommsDatabaseNotifications) { @@ -945,6 +1003,20 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) QMutexLocker locker(&mutex); switch (aEvent.EventType()) { +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + case EConnMonBearerInfoChange: + { + CConnMonBearerInfoChange* realEvent; + realEvent = (CConnMonBearerInfoChange*) &aEvent; + TUint connectionId = realEvent->ConnectionId(); + if (connectionId == EBearerIdAll) { + //Network level event + TConnMonBearerInfo bearerInfo = (TConnMonBearerInfo)realEvent->BearerInfo(); + updateMobileBearerToConfigs(bearerInfo); + } + break; + } +#endif case EConnMonConnectionStatusChange: { CConnMonConnectionStatusChange* realEvent; @@ -960,14 +1032,23 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) TRequestStatus status; iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); User::WaitForRequest(status); - QString ident = QString::number(qHash(apId)); + + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); +#ifdef OCC_FUNCTIONALITY_AVAILABLE + if (!ptr) { + // Check if status was regarding EasyWLAN + ptr = configurationFromEasyWlan(apId, connectionId); + } +#endif if (ptr) { ptr->mutex.lock(); toSymbianConfig(ptr)->connectionId = connectionId; ptr->mutex.unlock(); - emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(), - connectionId, QNetworkSession::Connecting); + QT_TRYCATCH_LEAVING( + emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(), + connectionId, QNetworkSession::Connecting) + ); } } else if (connectionStatus == KLinkLayerOpen) { // Connection has been successfully opened @@ -977,31 +1058,41 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) TRequestStatus status; iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); User::WaitForRequest(status); - QString ident = QString::number(qHash(apId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); +#ifdef OCC_FUNCTIONALITY_AVAILABLE + if (!ptr) { + // Check for EasyWLAN + ptr = configurationFromEasyWlan(apId, connectionId); + } +#endif if (ptr) { ptr->mutex.lock(); toSymbianConfig(ptr)->connectionId = connectionId; ptr->mutex.unlock(); // Configuration is Active - if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active)) { - updateStatesToSnaps(); - } - emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(), - connectionId, QNetworkSession::Connected); + QT_TRYCATCH_LEAVING( + if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active)) { + updateStatesToSnaps(); + } + emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(), + connectionId, QNetworkSession::Connected); - if (!iOnline) { - iOnline = true; - emit this->onlineStateChanged(iOnline); - } + if (!iOnline) { + iOnline = true; + emit this->onlineStateChanged(iOnline); + } + ); } } else if (connectionStatus == KConfigDaemonStartingDeregistration) { TUint connectionId = realEvent->ConnectionId(); QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId); if (ptr) { - emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(), - connectionId, QNetworkSession::Closing); + QT_TRYCATCH_LEAVING( + emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(), + connectionId, QNetworkSession::Closing) + ); } } else if (connectionStatus == KLinkLayerClosed || connectionStatus == KConnectionClosed) { @@ -1011,12 +1102,13 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId); if (ptr) { // Configuration is either Defined or Discovered - if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) { - updateStatesToSnaps(); - } - - emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(), - connectionId, QNetworkSession::Disconnected); + QT_TRYCATCH_LEAVING( + if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) { + updateStatesToSnaps(); + } + emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(), + connectionId, QNetworkSession::Disconnected); + ); } bool online = false; @@ -1030,7 +1122,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) } if (iOnline != online) { iOnline = online; - emit this->onlineStateChanged(iOnline); + QT_TRYCATCH_LEAVING(emit this->onlineStateChanged(iOnline)); } } } @@ -1043,12 +1135,13 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) TConnMonIapInfo iaps = realEvent->IapAvailability(); QList<QString> unDiscoveredConfigs = accessPointConfigurations.keys(); for ( TUint i = 0; i < iaps.Count(); i++ ) { - QString ident = QString::number(qHash(iaps.iIap[i].iIapId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX + + QString::number(qHash(iaps.iIap[i].iIapId)); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); if (ptr) { // Configuration is either Discovered or Active - changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered); + QT_TRYCATCH_LEAVING(changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered)); unDiscoveredConfigs.removeOne(ident); } } @@ -1056,7 +1149,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface); if (ptr) { // Configuration is Defined - changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined); + QT_TRYCATCH_LEAVING(changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined)); } } } @@ -1073,8 +1166,14 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) TRequestStatus status; iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); User::WaitForRequest(status); - QString ident = QString::number(qHash(apId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId)); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); +#ifdef OCC_FUNCTIONALITY_AVAILABLE + if (!ptr) { + // If IAP was not found, check if the update was about EasyWLAN + ptr = configurationFromEasyWlan(apId, connectionId); + } +#endif if (ptr) { QMutexLocker configLocker(&ptr->mutex); #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG @@ -1090,6 +1189,43 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) } } +#ifdef OCC_FUNCTIONALITY_AVAILABLE +// Tries to derive configuration from EasyWLAN. +// First checks if the interface brought up was EasyWLAN, then derives the real SSID, +// and looks up configuration based on that one. +QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromEasyWlan(TUint32 apId, TUint connectionId) +{ + if (apId == iCmManager.EasyWlanIdL()) { + TRequestStatus status; + TBuf<50> easyWlanNetworkName; + iConnectionMonitor.GetStringAttribute( connectionId, 0, KNetworkName, + easyWlanNetworkName, status ); + User::WaitForRequest(status); + if (status.Int() == KErrNone) { + QString realSSID = QString::fromUtf16(easyWlanNetworkName.Ptr(), easyWlanNetworkName.Length()); + + // Browser through all items and check their name for match + QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i = + accessPointConfigurations.constBegin(); + while (i != accessPointConfigurations.constEnd()) { + QNetworkConfigurationPrivatePointer ptr = i.value(); + + QMutexLocker configLocker(&ptr->mutex); + + if (ptr->name == realSSID) { +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug() << "QNCM EasyWlan uses real SSID: " << realSSID; +#endif + return ptr; + } + ++i; + } + } + } + return QNetworkConfigurationPrivatePointer(); +} +#endif + // Sessions may use this function to report configuration state changes, // because on some Symbian platforms (especially Symbian^3) all state changes are not // reported by the RConnectionMonitor, in particular in relation to stop() call, @@ -1107,7 +1243,8 @@ void SymbianEngine::configurationStateChangeReport(TUint32 accessPointId, QNetwo switch (newState) { case QNetworkSession::Disconnected: { - QString ident = QString::number(qHash(accessPointId)); + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX + + QString::number(qHash(accessPointId)); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); if (ptr) { // Configuration is either Defined or Discovered @@ -1129,15 +1266,13 @@ void SymbianEngine::configurationStateChangeReport(TUint32 accessPointId, QNetwo } // Waits for 2..6 seconds. -void SymbianEngine::waitRandomTime() +void SymbianEngine::updateConfigurationsAfterRandomTime() { - int iTimeToWait = qMax(2000, (qAbs(qrand()) % 7) * 1000); + int iTimeToWait = qMax(1000, (qAbs(qrand()) % 68) * 100); #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG qDebug("QNCM waiting random time: %d ms", iTimeToWait); #endif - QEventLoop loop; - QTimer::singleShot(iTimeToWait, &loop, SLOT(quit())); - loop.exec(); + QTimer::singleShot(iTimeToWait, this, SLOT(delayedConfigurationUpdate())); } QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aConnectionId) @@ -1158,7 +1293,7 @@ QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aCon AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(SymbianEngine& owner, RConnectionMonitor& connectionMonitor) - : CActive(CActive::EPriorityStandard), iOwner(owner), iConnectionMonitor(connectionMonitor) + : CActive(CActive::EPriorityHigh), iOwner(owner), iConnectionMonitor(connectionMonitor) { CActiveScheduler::Add(this); } @@ -1198,9 +1333,9 @@ void AccessPointsAvailabilityScanner::RunL() if (iStatus.Int() != KErrNone) { iIapBuf().iCount = 0; - iOwner.accessPointScanningReady(false,iIapBuf()); + QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(false,iIapBuf())); } else { - iOwner.accessPointScanningReady(true,iIapBuf()); + QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(true,iIapBuf())); } } diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h index 18fd249..cfddc29 100644 --- a/src/plugins/bearer/symbian/symbianengine.h +++ b/src/plugins/bearer/symbian/symbianengine.h @@ -55,6 +55,9 @@ // Uncomment and compile QtBearer to gain detailed state tracing // #define QT_BEARERMGMT_SYMBIAN_DEBUG +#define QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX QLatin1String("S_") +#define QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX QLatin1String("I_") + class CCommsDatabase; class QEventLoop; @@ -159,6 +162,7 @@ Q_SIGNALS: public Q_SLOTS: void updateConfigurations(); + void delayedConfigurationUpdate(); private: void updateStatesToSnaps(); @@ -169,6 +173,7 @@ private: bool changeConfigurationStateAtMaxTo(QNetworkConfigurationPrivatePointer ptr, QNetworkConfiguration::StateFlags newState); #ifdef SNAP_FUNCTIONALITY_AVAILABLE + void updateMobileBearerToConfigs(TConnMonBearerInfo bearerInfo); SymbianNetworkConfigurationPrivate *configFromConnectionMethodL(RCmConnectionMethod& connectionMethod); #else bool readNetworkConfigurationValuesFromCommsDb( @@ -183,7 +188,7 @@ private: void accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo); void startCommsDatabaseNotifications(); void stopCommsDatabaseNotifications(); - void waitRandomTime(); + void updateConfigurationsAfterRandomTime(); QNetworkConfigurationPrivatePointer defaultConfigurationL(); TBool GetS60PlatformVersion(TUint& aMajor, TUint& aMinor) const; @@ -201,6 +206,9 @@ private: // For QNetworkSessionPrivate to indicate about state changes void configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState); +#ifdef OCC_FUNCTIONALITY_AVAILABLE + QNetworkConfigurationPrivatePointer configurationFromEasyWlan(TUint32 apId, TUint connectionId); +#endif private: // Data bool iFirstUpdate; @@ -211,7 +219,7 @@ private: // Data TBool iOnline; TBool iInitOk; TBool iUpdateGoingOn; - TBool iIgnoringUpdates; + TBool iUpdatePending; AccessPointsAvailabilityScanner* ipAccessPointsAvailabilityScanner; diff --git a/src/plugins/codecs/cn/qgb18030codec.cpp b/src/plugins/codecs/cn/qgb18030codec.cpp index 3f2eec7..e10c8b1 100644 --- a/src/plugins/codecs/cn/qgb18030codec.cpp +++ b/src/plugins/codecs/cn/qgb18030codec.cpp @@ -319,7 +319,7 @@ QString QGbkCodec::convertToUnicode(const char* chars, int len, ConverterState * { uchar buf[2]; int nbuf = 0; - QChar replacement = QChar::ReplacementCharacter; + ushort replacement = QChar::ReplacementCharacter; if (state) { if (state->flags & ConvertInvalidToNull) replacement = QChar::Null; @@ -330,6 +330,9 @@ QString QGbkCodec::convertToUnicode(const char* chars, int len, ConverterState * int invalid = 0; QString result; + result.resize(len); + int unicodeLen = 0; + ushort *const resultData = reinterpret_cast<ushort*>(result.data()); //qDebug("QGbkDecoder::toUnicode(const char* chars = \"%s\", int len = %d)", chars, len); for (int i=0; i<len; i++) { @@ -338,14 +341,16 @@ QString QGbkCodec::convertToUnicode(const char* chars, int len, ConverterState * case 0: if (ch < 0x80) { // ASCII - result += QLatin1Char(ch); + resultData[unicodeLen] = ch; + ++unicodeLen; } else if (Is1stByte(ch)) { // GBK 1st byte? buf[0] = ch; nbuf = 1; } else { // Invalid - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; } break; @@ -356,21 +361,25 @@ QString QGbkCodec::convertToUnicode(const char* chars, int len, ConverterState * int clen = 2; uint u = qt_Gb18030ToUnicode(buf, clen); if (clen == 2) { - result += qValidChar(u); + resultData[unicodeLen] = qValidChar(static_cast<ushort>(u)); + ++unicodeLen; } else { - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; } nbuf = 0; } else { // Error - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; nbuf = 0; } break; } } + result.resize(unicodeLen); if (state) { state->remainingChars = nbuf; diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index a093e4c..4addb84 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -175,13 +175,6 @@ symbian: { particlesImport.path = c:$$QT_IMPORTS_BASE_DIR/Qt/labs/particles DEPLOYMENT += folderlistmodelImport gesturesImport particlesImport - - contains(QT_CONFIG, webkit): { - webkitImport.sources = $$QT_BUILD_TREE/imports/QtWebKit/qmlwebkitplugin$${QT_LIBINFIX}.dll - webkitImport.sources += $$QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/declarative/qmldir - webkitImport.path = c:$$QT_IMPORTS_BASE_DIR/QtWebKit - DEPLOYMENT += webkitImport - } } graphicssystems_plugins.path = c:$$QT_PLUGINS_BASE_DIR/graphicssystems diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index e2999c1..7bccffe 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -64,6 +64,7 @@ #include "bridge/qscriptqobject_p.h" #include "bridge/qscriptglobalobject_p.h" #include "bridge/qscriptactivationobject_p.h" +#include "bridge/qscriptstaticscopeobject_p.h" #ifndef QT_NO_QOBJECT #include <QtCore/qcoreapplication.h> @@ -437,6 +438,53 @@ qsreal ToNumber(const QString &value) #endif +static const qsreal MsPerSecond = 1000.0; + +static inline int MsFromTime(qsreal t) +{ + int r = int(::fmod(t, MsPerSecond)); + return (r >= 0) ? r : r + int(MsPerSecond); +} + +/*! + \internal + Converts a JS date value (milliseconds) to a QDateTime (local time). +*/ +QDateTime MsToDateTime(JSC::ExecState *exec, qsreal t) +{ + if (qIsNaN(t)) + return QDateTime(); + JSC::GregorianDateTime tm; + JSC::msToGregorianDateTime(exec, t, /*output UTC=*/true, tm); + int ms = MsFromTime(t); + QDateTime convertedUTC = QDateTime(QDate(tm.year + 1900, tm.month + 1, tm.monthDay), + QTime(tm.hour, tm.minute, tm.second, ms), Qt::UTC); + return convertedUTC.toLocalTime(); +} + +/*! + \internal + Converts a QDateTime to a JS date value (milliseconds). +*/ +qsreal DateTimeToMs(JSC::ExecState *exec, const QDateTime &dt) +{ + if (!dt.isValid()) + return qSNaN(); + QDateTime utc = dt.toUTC(); + QDate date = utc.date(); + QTime time = utc.time(); + JSC::GregorianDateTime tm; + tm.year = date.year() - 1900; + tm.month = date.month() - 1; + tm.monthDay = date.day(); + tm.weekDay = date.dayOfWeek(); + tm.yearDay = date.dayOfYear(); + tm.hour = time.hour(); + tm.minute = time.minute(); + tm.second = time.second(); + return JSC::gregorianDateTimeToMS(exec, tm, time.msec(), /*inputIsUTC=*/true); +} + void GlobalClientData::mark(JSC::MarkStack& markStack) { engine->mark(markStack); @@ -905,6 +953,7 @@ QScriptEnginePrivate::QScriptEnginePrivate() JSC::ExecState* exec = globalObject->globalExec(); scriptObjectStructure = QScriptObject::createStructure(globalObject->objectPrototype()); + staticScopeObjectStructure = QScriptStaticScopeObject::createStructure(JSC::jsNull()); qobjectPrototype = new (exec) QScript::QObjectPrototype(exec, QScript::QObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); qobjectWrapperObjectStructure = QScriptObject::createStructure(qobjectPrototype); @@ -1770,15 +1819,7 @@ void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue object } else if (flags != QScriptValue::KeepExistingFlags) { if (thisObject->hasOwnProperty(exec, id)) thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes? - unsigned attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - attribs |= flags & QScriptValue::UserRange; - thisObject->putWithAttributes(exec, id, value, attribs); + thisObject->putWithAttributes(exec, id, value, propertyFlagsToJSCAttributes(flags)); } else { JSC::PutPropertySlot slot; thisObject->put(exec, id, value, slot); diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 56366e2..c71465d 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -50,7 +50,6 @@ #include "bridge/qscriptobject_p.h" #include "bridge/qscriptqobject_p.h" #include "bridge/qscriptvariant_p.h" -#include "utils/qscriptdate_p.h" #include "DateConstructor.h" #include "DateInstance.h" @@ -119,6 +118,9 @@ namespace QScript inline QString ToString(qsreal); #endif + QDateTime MsToDateTime(JSC::ExecState *, qsreal); + qsreal DateTimeToMs(JSC::ExecState *, const QDateTime &); + //some conversion helper functions inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); bool isFunction(JSC::JSValue value); @@ -205,6 +207,7 @@ public: inline QScriptValue scriptValueFromJSCValue(JSC::JSValue value); inline JSC::JSValue scriptValueToJSCValue(const QScriptValue &value); + static inline unsigned propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags &flags); static inline JSC::JSValue jscValueFromVariant(JSC::ExecState*, const QVariant &value); static QVariant jscValueToVariant(JSC::ExecState*, JSC::JSValue value, int targetType); @@ -346,6 +349,7 @@ public: JSC::ExecState *currentFrame; WTF::RefPtr<JSC::Structure> scriptObjectStructure; + WTF::RefPtr<JSC::Structure> staticScopeObjectStructure; QScript::QObjectPrototype *qobjectPrototype; WTF::RefPtr<JSC::Structure> qobjectWrapperObjectStructure; @@ -639,6 +643,19 @@ inline JSC::JSValue QScriptEnginePrivate::scriptValueToJSCValue(const QScriptVal return vv->jscValue; } +inline unsigned QScriptEnginePrivate::propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags &flags) +{ + unsigned attribs = 0; + if (flags & QScriptValue::ReadOnly) + attribs |= JSC::ReadOnly; + if (flags & QScriptValue::SkipInEnumeration) + attribs |= JSC::DontEnum; + if (flags & QScriptValue::Undeletable) + attribs |= JSC::DontDelete; + attribs |= flags & QScriptValue::UserRange; + return attribs; +} + inline QScriptValuePrivate::~QScriptValuePrivate() { if (engine) @@ -846,7 +863,7 @@ inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, qsreal v inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, const QDateTime &value) { - return newDate(exec, QScript::FromDateTime(value)); + return newDate(exec, QScript::DateTimeToMs(exec, value)); } inline JSC::JSValue QScriptEnginePrivate::newObject() @@ -979,12 +996,12 @@ inline JSC::UString QScriptEnginePrivate::toString(JSC::ExecState *exec, JSC::JS return str; } -inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *, JSC::JSValue value) +inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *exec, JSC::JSValue value) { if (!isDate(value)) return QDateTime(); qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(value))->internalNumber(); - return QScript::ToDateTime(t, Qt::LocalTime); + return QScript::MsToDateTime(exec, t); } inline QObject *QScriptEnginePrivate::toQObject(JSC::ExecState *exec, JSC::JSValue value) diff --git a/src/script/bridge/bridge.pri b/src/script/bridge/bridge.pri index 09e2dfb..ab0a322 100644 --- a/src/script/bridge/bridge.pri +++ b/src/script/bridge/bridge.pri @@ -6,6 +6,7 @@ SOURCES += \ $$PWD/qscriptqobject.cpp \ $$PWD/qscriptglobalobject.cpp \ $$PWD/qscriptactivationobject.cpp \ + $$PWD/qscriptstaticscopeobject.cpp \ $$PWD/qscriptdeclarativeobject.cpp \ $$PWD/qscriptdeclarativeclass.cpp @@ -17,5 +18,6 @@ HEADERS += \ $$PWD/qscriptqobject_p.h \ $$PWD/qscriptglobalobject_p.h \ $$PWD/qscriptactivationobject_p.h \ + $$PWD/qscriptstaticscopeobject_p.h \ $$PWD/qscriptdeclarativeobject_p.h \ $$PWD/qscriptdeclarativeclass_p.h diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index 1093448..8080b9f 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -24,6 +24,7 @@ #include "qscriptdeclarativeclass_p.h" #include "qscriptdeclarativeobject_p.h" #include "qscriptobject_p.h" +#include "qscriptstaticscopeobject_p.h" #include <QtScript/qscriptstring.h> #include <QtScript/qscriptengine.h> #include <QtScript/qscriptengineagent.h> @@ -549,4 +550,39 @@ QScriptContext *QScriptDeclarativeClass::context() const return d_ptr->context; } +/*! + Creates a scope object with a fixed set of undeletable properties. +*/ +QScriptValue QScriptDeclarativeClass::newStaticScopeObject( + QScriptEngine *engine, int propertyCount, const QString *names, + const QScriptValue *values, const QScriptValue::PropertyFlags *flags) +{ + QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); + QScript::APIShim shim(eng_p); + JSC::ExecState *exec = eng_p->currentFrame; + QScriptStaticScopeObject::PropertyInfo *props = new QScriptStaticScopeObject::PropertyInfo[propertyCount]; + for (int i = 0; i < propertyCount; ++i) { + unsigned attribs = QScriptEnginePrivate::propertyFlagsToJSCAttributes(flags[i]); + Q_ASSERT_X(attribs & JSC::DontDelete, Q_FUNC_INFO, "All properties must be undeletable"); + JSC::Identifier id = JSC::Identifier(exec, names[i]); + JSC::JSValue jsval = eng_p->scriptValueToJSCValue(values[i]); + props[i] = QScriptStaticScopeObject::PropertyInfo(id, jsval, attribs); + } + QScriptValue result = eng_p->scriptValueFromJSCValue(new (exec)QScriptStaticScopeObject(eng_p->staticScopeObjectStructure, + propertyCount, props)); + delete[] props; + return result; +} + +/*! + Creates a static scope object that's initially empty, but to which new + properties can be added. +*/ +QScriptValue QScriptDeclarativeClass::newStaticScopeObject(QScriptEngine *engine) +{ + QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); + QScript::APIShim shim(eng_p); + return eng_p->scriptValueFromJSCValue(new (eng_p->currentFrame)QScriptStaticScopeObject(eng_p->staticScopeObjectStructure)); +} + QT_END_NAMESPACE diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index 714a67c..420b133 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -92,6 +92,11 @@ public: static QScriptValue scopeChainValue(QScriptContext *, int index); static QScriptContext *pushCleanContext(QScriptEngine *); + static QScriptValue newStaticScopeObject( + QScriptEngine *, int propertyCount, const QString *names, + const QScriptValue *values, const QScriptValue::PropertyFlags *flags); + static QScriptValue newStaticScopeObject(QScriptEngine *); + class Q_SCRIPT_EXPORT PersistentIdentifier { public: diff --git a/src/script/bridge/qscriptstaticscopeobject.cpp b/src/script/bridge/qscriptstaticscopeobject.cpp new file mode 100644 index 0000000..44548a4 --- /dev/null +++ b/src/script/bridge/qscriptstaticscopeobject.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-ONLY$ +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptstaticscopeobject_p.h" + +namespace JSC +{ + ASSERT_CLASS_FITS_IN_CELL(QT_PREPEND_NAMESPACE(QScriptStaticScopeObject)); +} + +QT_BEGIN_NAMESPACE + +/*! + \class QScriptStaticScopeObject + \internal + + Represents a static scope object. + + This class allows the VM to determine at JS script compile time whether + the object has a given property or not. If the object has the property, + a fast, index-based read/write operation will be used. If the object + doesn't have the property, the compiler knows it can safely skip this + object when dynamically resolving the property. Either way, this can + greatly improve performance. + + \sa QScriptContext::pushScope() +*/ + +const JSC::ClassInfo QScriptStaticScopeObject::info = { "QScriptStaticScopeObject", 0, 0, 0 }; + +/*! + Creates a static scope object with a fixed set of undeletable properties. + + It's not possible to add new properties to the object after construction. +*/ +QScriptStaticScopeObject::QScriptStaticScopeObject(WTF::NonNullPassRefPtr<JSC::Structure> structure, + int propertyCount, const PropertyInfo* props) + : JSC::JSVariableObject(structure, new Data(/*canGrow=*/false)) +{ + int index = growRegisterArray(propertyCount); + for (int i = 0; i < propertyCount; ++i, --index) { + const PropertyInfo& prop = props[i]; + JSC::SymbolTableEntry entry(index, prop.attributes); + symbolTable().add(prop.identifier.ustring().rep(), entry); + registerAt(index) = prop.value; + } +} + +/*! + Creates an empty static scope object. + + Properties can be added to the object after construction, either by + calling QScriptValue::setProperty(), or by pushing the object on the + scope chain; variable declarations ("var" statements) and function + declarations in JavaScript will create properties on the scope object. + + Note that once the scope object has been used in a closure and the + resulting function has been compiled, it's no longer safe to add + properties to the scope object (because the VM will bypass this + object the next time the function is executed). +*/ +QScriptStaticScopeObject::QScriptStaticScopeObject(WTF::NonNullPassRefPtr<JSC::Structure> structure) + : JSC::JSVariableObject(structure, new Data(/*canGrow=*/true)) +{ +} + +QScriptStaticScopeObject::~QScriptStaticScopeObject() +{ + delete d; +} + +bool QScriptStaticScopeObject::getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot& slot) +{ + return symbolTableGet(propertyName, slot); +} + +bool QScriptStaticScopeObject::getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor& descriptor) +{ + return symbolTableGet(propertyName, descriptor); +} + +void QScriptStaticScopeObject::putWithAttributes(JSC::ExecState* exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes) +{ + if (symbolTablePutWithAttributes(propertyName, value, attributes)) + return; + Q_ASSERT(d_ptr()->canGrow); + addSymbolTableProperty(propertyName, value, attributes); +} + +void QScriptStaticScopeObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot&) +{ + if (symbolTablePut(propertyName, value)) + return; + Q_ASSERT(d_ptr()->canGrow); + addSymbolTableProperty(propertyName, value, /*attributes=*/0); +} + +bool QScriptStaticScopeObject::deleteProperty(JSC::ExecState*, const JSC::Identifier&) +{ + return false; +} + +void QScriptStaticScopeObject::markChildren(JSC::MarkStack& markStack) +{ + JSC::Register* registerArray = d_ptr()->registerArray.get(); + if (!registerArray) + return; + markStack.appendValues(reinterpret_cast<JSC::JSValue*>(registerArray), d_ptr()->registerArraySize); +} + +void QScriptStaticScopeObject::addSymbolTableProperty(const JSC::Identifier& name, JSC::JSValue value, unsigned attributes) +{ + int index = growRegisterArray(1); + JSC::SymbolTableEntry newEntry(index, attributes | JSC::DontDelete); + symbolTable().add(name.ustring().rep(), newEntry); + registerAt(index) = value; +} + +/*! + Grows the register array by \a count elements, and returns the offset of + the newly added elements (note that the register file grows downwards, + starting at index -1). +*/ +int QScriptStaticScopeObject::growRegisterArray(int count) +{ + size_t oldSize = d_ptr()->registerArraySize; + size_t newSize = oldSize + count; + JSC::Register* registerArray = new JSC::Register[newSize]; + if (d_ptr()->registerArray) + memcpy(registerArray + count, d_ptr()->registerArray.get(), oldSize * sizeof(JSC::Register)); + setRegisters(registerArray + newSize, registerArray); + d_ptr()->registerArraySize = newSize; + return -oldSize - 1; +} + +QT_END_NAMESPACE diff --git a/src/script/bridge/qscriptstaticscopeobject_p.h b/src/script/bridge/qscriptstaticscopeobject_p.h new file mode 100644 index 0000000..0a0e7ef --- /dev/null +++ b/src/script/bridge/qscriptstaticscopeobject_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-ONLY$ +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTSTATICSCOPEOBJECT_P_H +#define QSCRIPTSTATICSCOPEOBJECT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include "JSVariableObject.h" + +QT_BEGIN_NAMESPACE + +class QScriptStaticScopeObject : public JSC::JSVariableObject { +public: + struct PropertyInfo { + PropertyInfo(const JSC::Identifier& i, JSC::JSValue v, unsigned a) + : identifier(i), value(v), attributes(a) + { } + PropertyInfo() {} + + JSC::Identifier identifier; + JSC::JSValue value; + unsigned attributes; + }; + + QScriptStaticScopeObject(WTF::NonNullPassRefPtr<JSC::Structure> structure, + int propertyCount, const PropertyInfo*); + QScriptStaticScopeObject(WTF::NonNullPassRefPtr<JSC::Structure> structure); + virtual ~QScriptStaticScopeObject(); + + virtual bool isDynamicScope() const { return false; } + + virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); + virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&); + + virtual void putWithAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes); + virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot&); + + virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName); + + virtual void markChildren(JSC::MarkStack&); + + virtual const JSC::ClassInfo* classInfo() const { return &info; } + static const JSC::ClassInfo info; + + static WTF::PassRefPtr<JSC::Structure> createStructure(JSC::JSValue proto) { + return JSC::Structure::create(proto, JSC::TypeInfo(JSC::ObjectType, StructureFlags)); + } + +protected: + static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::NeedsThisConversion | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames | JSC::JSVariableObject::StructureFlags; + + struct Data : public JSVariableObjectData { + Data(bool canGrow_) + : JSVariableObjectData(&symbolTable, /*registers=*/0), + canGrow(canGrow_), registerArraySize(0) + { } + bool canGrow; + int registerArraySize; + JSC::SymbolTable symbolTable; + }; + + Data* d_ptr() const { return static_cast<Data*>(JSVariableObject::d); } + +private: + void addSymbolTableProperty(const JSC::Identifier&, JSC::JSValue, unsigned attributes); + int growRegisterArray(int); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/script/script.pri b/src/script/script.pri index 2ee1a82..9cd71d3 100644 --- a/src/script/script.pri +++ b/src/script/script.pri @@ -1,4 +1,3 @@ include($$PWD/api/api.pri) include($$PWD/bridge/bridge.pri) include($$PWD/parser/parser.pri) -include($$PWD/utils/utils.pri) diff --git a/src/script/utils/qscriptdate.cpp b/src/script/utils/qscriptdate.cpp deleted file mode 100644 index 5980256..0000000 --- a/src/script/utils/qscriptdate.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptdate_p.h" - -#include <QtCore/qnumeric.h> -#include <QtCore/qstringlist.h> - -#include <math.h> - -#ifndef Q_WS_WIN -# include <time.h> -# include <sys/time.h> -#else -# include <windows.h> -#endif - -QT_BEGIN_NAMESPACE - -namespace QScript { - -qsreal ToInteger(qsreal n); - -static const qsreal HoursPerDay = 24.0; -static const qsreal MinutesPerHour = 60.0; -static const qsreal SecondsPerMinute = 60.0; -static const qsreal msPerSecond = 1000.0; -static const qsreal msPerMinute = 60000.0; -static const qsreal msPerHour = 3600000.0; -static const qsreal msPerDay = 86400000.0; - -static qsreal LocalTZA = 0.0; // initialized at startup - -static inline qsreal TimeWithinDay(qsreal t) -{ - qsreal r = ::fmod(t, msPerDay); - return (r >= 0) ? r : r + msPerDay; -} - -static inline int HourFromTime(qsreal t) -{ - int r = int(::fmod(::floor(t / msPerHour), HoursPerDay)); - return (r >= 0) ? r : r + int(HoursPerDay); -} - -static inline int MinFromTime(qsreal t) -{ - int r = int(::fmod(::floor(t / msPerMinute), MinutesPerHour)); - return (r >= 0) ? r : r + int(MinutesPerHour); -} - -static inline int SecFromTime(qsreal t) -{ - int r = int(::fmod(::floor(t / msPerSecond), SecondsPerMinute)); - return (r >= 0) ? r : r + int(SecondsPerMinute); -} - -static inline int msFromTime(qsreal t) -{ - int r = int(::fmod(t, msPerSecond)); - return (r >= 0) ? r : r + int(msPerSecond); -} - -static inline qsreal Day(qsreal t) -{ - return ::floor(t / msPerDay); -} - -static inline qsreal DaysInYear(qsreal y) -{ - if (::fmod(y, 4)) - return 365; - - else if (::fmod(y, 100)) - return 366; - - else if (::fmod(y, 400)) - return 365; - - return 366; -} - -static inline qsreal DayFromYear(qsreal y) -{ - return 365 * (y - 1970) - + ::floor((y - 1969) / 4) - - ::floor((y - 1901) / 100) - + ::floor((y - 1601) / 400); -} - -static inline qsreal TimeFromYear(qsreal y) -{ - return msPerDay * DayFromYear(y); -} - -static inline qsreal YearFromTime(qsreal t) -{ - int y = 1970; - y += (int) ::floor(t / (msPerDay * 365.2425)); - - qsreal t2 = TimeFromYear(y); - return (t2 > t) ? y - 1 : ((t2 + msPerDay * DaysInYear(y)) <= t) ? y + 1 : y; -} - -static inline bool InLeapYear(qsreal t) -{ - qsreal x = DaysInYear(YearFromTime(t)); - if (x == 365) - return 0; - - Q_ASSERT (x == 366); - return 1; -} - -static inline qsreal DayWithinYear(qsreal t) -{ - return Day(t) - DayFromYear(YearFromTime(t)); -} - -static inline qsreal MonthFromTime(qsreal t) -{ - qsreal d = DayWithinYear(t); - qsreal l = InLeapYear(t); - - if (d < 31.0) - return 0; - - else if (d < 59.0 + l) - return 1; - - else if (d < 90.0 + l) - return 2; - - else if (d < 120.0 + l) - return 3; - - else if (d < 151.0 + l) - return 4; - - else if (d < 181.0 + l) - return 5; - - else if (d < 212.0 + l) - return 6; - - else if (d < 243.0 + l) - return 7; - - else if (d < 273.0 + l) - return 8; - - else if (d < 304.0 + l) - return 9; - - else if (d < 334.0 + l) - return 10; - - else if (d < 365.0 + l) - return 11; - - return qSNaN(); // ### assert? -} - -static inline qsreal DateFromTime(qsreal t) -{ - int m = (int) ToInteger(MonthFromTime(t)); - qsreal d = DayWithinYear(t); - qsreal l = InLeapYear(t); - - switch (m) { - case 0: return d + 1.0; - case 1: return d - 30.0; - case 2: return d - 58.0 - l; - case 3: return d - 89.0 - l; - case 4: return d - 119.0 - l; - case 5: return d - 150.0 - l; - case 6: return d - 180.0 - l; - case 7: return d - 211.0 - l; - case 8: return d - 242.0 - l; - case 9: return d - 272.0 - l; - case 10: return d - 303.0 - l; - case 11: return d - 333.0 - l; - } - - return qSNaN(); // ### assert -} - -static inline qsreal WeekDay(qsreal t) -{ - qsreal r = ::fmod (Day(t) + 4.0, 7.0); - return (r >= 0) ? r : r + 7.0; -} - - -static inline qsreal MakeTime(qsreal hour, qsreal min, qsreal sec, qsreal ms) -{ - return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms; -} - -static inline qsreal DayFromMonth(qsreal month, qsreal leap) -{ - switch ((int) month) { - case 0: return 0; - case 1: return 31.0; - case 2: return 59.0 + leap; - case 3: return 90.0 + leap; - case 4: return 120.0 + leap; - case 5: return 151.0 + leap; - case 6: return 181.0 + leap; - case 7: return 212.0 + leap; - case 8: return 243.0 + leap; - case 9: return 273.0 + leap; - case 10: return 304.0 + leap; - case 11: return 334.0 + leap; - } - - return qSNaN(); // ### assert? -} - -static qsreal MakeDay(qsreal year, qsreal month, qsreal day) -{ - year += ::floor(month / 12.0); - - month = ::fmod(month, 12.0); - if (month < 0) - month += 12.0; - - qsreal t = TimeFromYear(year); - qsreal leap = InLeapYear(t); - - day += ::floor(t / msPerDay); - day += DayFromMonth(month, leap); - - return day - 1; -} - -static inline qsreal MakeDate(qsreal day, qsreal time) -{ - return day * msPerDay + time; -} - -static inline qsreal DaylightSavingTA(double t) -{ -#ifndef Q_WS_WIN - long int tt = (long int)(t / msPerSecond); - struct tm *tmtm = localtime((const time_t*)&tt); - if (! tmtm) - return 0; - return (tmtm->tm_isdst > 0) ? msPerHour : 0; -#else - Q_UNUSED(t); - /// ### implement me - return 0; -#endif -} - -static inline qsreal LocalTime(qsreal t) -{ - return t + LocalTZA + DaylightSavingTA(t); -} - -static inline qsreal UTC(qsreal t) -{ - return t - LocalTZA - DaylightSavingTA(t - LocalTZA); -} - -static inline qsreal TimeClip(qsreal t) -{ - if (! qIsFinite(t) || fabs(t) > 8.64e15) - return qSNaN(); - return ToInteger(t); -} - -static qsreal getLocalTZA() -{ -#ifndef Q_WS_WIN - struct tm* t; - time_t curr; - time(&curr); - t = localtime(&curr); - time_t locl = mktime(t); - t = gmtime(&curr); - time_t globl = mktime(t); - return double(locl - globl) * 1000.0; -#else - TIME_ZONE_INFORMATION tzInfo; - GetTimeZoneInformation(&tzInfo); - return -tzInfo.Bias * 60.0 * 1000.0; -#endif -} - -/*! - \internal - - Converts the QDateTime \a dt to an ECMA Date value (in UTC form). -*/ -qsreal FromDateTime(const QDateTime &dt) -{ - if (!dt.isValid()) - return qSNaN(); - if (!LocalTZA) // ### move - LocalTZA = getLocalTZA(); - QDate date = dt.date(); - QTime taim = dt.time(); - int year = date.year(); - int month = date.month() - 1; - int day = date.day(); - int hours = taim.hour(); - int mins = taim.minute(); - int secs = taim.second(); - int ms = taim.msec(); - double t = MakeDate(MakeDay(year, month, day), - MakeTime(hours, mins, secs, ms)); - if (dt.timeSpec() == Qt::LocalTime) - t = UTC(t); - return TimeClip(t); -} - -/*! - \internal - - Converts the ECMA Date value \tt (in UTC form) to QDateTime - according to \a spec. -*/ -QDateTime ToDateTime(qsreal t, Qt::TimeSpec spec) -{ - if (qIsNaN(t)) - return QDateTime(); - if (!LocalTZA) // ### move - LocalTZA = getLocalTZA(); - if (spec == Qt::LocalTime) - t = LocalTime(t); - int year = int(YearFromTime(t)); - int month = int(MonthFromTime(t) + 1); - int day = int(DateFromTime(t)); - int hours = HourFromTime(t); - int mins = MinFromTime(t); - int secs = SecFromTime(t); - int ms = msFromTime(t); - return QDateTime(QDate(year, month, day), QTime(hours, mins, secs, ms), spec); -} - -} // namespace QScript - -QT_END_NAMESPACE diff --git a/src/script/utils/qscriptdate_p.h b/src/script/utils/qscriptdate_p.h deleted file mode 100644 index b9c9fd4..0000000 --- a/src/script/utils/qscriptdate_p.h +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTDATE_P_H -#define QSCRIPTDATE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qdatetime.h> - -QT_BEGIN_NAMESPACE - -typedef double qsreal; - -namespace QScript -{ - qsreal FromDateTime(const QDateTime &dt); - QDateTime ToDateTime(qsreal t, Qt::TimeSpec spec); -} - -QT_END_NAMESPACE - -#endif diff --git a/src/script/utils/utils.pri b/src/script/utils/utils.pri deleted file mode 100644 index d8302d5..0000000 --- a/src/script/utils/utils.pri +++ /dev/null @@ -1,5 +0,0 @@ -SOURCES += \ - $$PWD/qscriptdate.cpp - -HEADERS += \ - $$PWD/qscriptdate_p.h diff --git a/src/src.pro b/src/src.pro index 0d7404d..0573c2d 100644 --- a/src/src.pro +++ b/src/src.pro @@ -18,13 +18,13 @@ contains(QT_CONFIG, xmlpatterns): SRC_SUBDIRS += src_xmlpatterns contains(QT_CONFIG, phonon): SRC_SUBDIRS += src_phonon contains(QT_CONFIG, multimedia): SRC_SUBDIRS += src_multimedia contains(QT_CONFIG, svg): SRC_SUBDIRS += src_svg +contains(QT_CONFIG, script): SRC_SUBDIRS += src_script +contains(QT_CONFIG, declarative): SRC_SUBDIRS += src_declarative contains(QT_CONFIG, webkit) { exists($$QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro): SRC_SUBDIRS += src_javascriptcore SRC_SUBDIRS += src_webkit } -contains(QT_CONFIG, script): SRC_SUBDIRS += src_script !contains(QT_CONFIG, no-gui):contains(QT_CONFIG, scripttools): SRC_SUBDIRS += src_scripttools -contains(QT_CONFIG, declarative): SRC_SUBDIRS += src_declarative SRC_SUBDIRS += src_plugins contains(QT_CONFIG, declarative): SRC_SUBDIRS += src_imports contains(QT_CONFIG, declarative):contains(QT_CONFIG, webkit): SRC_SUBDIRS += src_webkit_declarative |