| Index: skia/views/SkEventSink.cpp
|
| ===================================================================
|
| --- skia/views/SkEventSink.cpp (revision 16859)
|
| +++ skia/views/SkEventSink.cpp (working copy)
|
| @@ -1,345 +0,0 @@
|
| -/* libs/graphics/views/SkEventSink.cpp
|
| -**
|
| -** Copyright 2006, The Android Open Source Project
|
| -**
|
| -** Licensed under the Apache License, Version 2.0 (the "License");
|
| -** you may not use this file except in compliance with the License.
|
| -** You may obtain a copy of the License at
|
| -**
|
| -** http://www.apache.org/licenses/LICENSE-2.0
|
| -**
|
| -** Unless required by applicable law or agreed to in writing, software
|
| -** distributed under the License is distributed on an "AS IS" BASIS,
|
| -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| -** See the License for the specific language governing permissions and
|
| -** limitations under the License.
|
| -*/
|
| -
|
| -#include "SkEventSink.h"
|
| -#include "SkTagList.h"
|
| -#include "SkThread.h"
|
| -
|
| -#include "SkGlobals.h"
|
| -#include "SkThread.h"
|
| -#include "SkTime.h"
|
| -
|
| -#define SK_EventSink_GlobalsTag SkSetFourByteTag('e', 'v', 's', 'k')
|
| -
|
| -class SkEventSink_Globals : public SkGlobals::Rec {
|
| -public:
|
| - SkMutex fSinkMutex;
|
| - SkEventSinkID fNextSinkID;
|
| - SkEventSink* fSinkHead;
|
| -};
|
| -
|
| -static SkGlobals::Rec* create_globals()
|
| -{
|
| - SkEventSink_Globals* rec = new SkEventSink_Globals;
|
| - rec->fNextSinkID = 0;
|
| - rec->fSinkHead = NULL;
|
| - return rec;
|
| -}
|
| -
|
| -SkEventSink::SkEventSink() : fTagHead(NULL)
|
| -{
|
| - SkEventSink_Globals& globals = *(SkEventSink_Globals*)SkGlobals::Find(SK_EventSink_GlobalsTag, create_globals);
|
| -
|
| - globals.fSinkMutex.acquire();
|
| -
|
| - fID = ++globals.fNextSinkID;
|
| - fNextSink = globals.fSinkHead;
|
| - globals.fSinkHead = this;
|
| -
|
| - globals.fSinkMutex.release();
|
| -}
|
| -
|
| -SkEventSink::~SkEventSink()
|
| -{
|
| - SkEventSink_Globals& globals = *(SkEventSink_Globals*)SkGlobals::Find(SK_EventSink_GlobalsTag, create_globals);
|
| -
|
| - if (fTagHead)
|
| - SkTagList::DeleteAll(fTagHead);
|
| -
|
| - globals.fSinkMutex.acquire();
|
| -
|
| - SkEventSink* sink = globals.fSinkHead;
|
| - SkEventSink* prev = NULL;
|
| -
|
| - for (;;)
|
| - {
|
| - SkEventSink* next = sink->fNextSink;
|
| - if (sink == this)
|
| - {
|
| - if (prev)
|
| - prev->fNextSink = next;
|
| - else
|
| - globals.fSinkHead = next;
|
| - break;
|
| - }
|
| - prev = sink;
|
| - sink = next;
|
| - }
|
| - globals.fSinkMutex.release();
|
| -}
|
| -
|
| -bool SkEventSink::doEvent(const SkEvent& evt)
|
| -{
|
| - return this->onEvent(evt);
|
| -}
|
| -
|
| -bool SkEventSink::doQuery(SkEvent* evt)
|
| -{
|
| - SkASSERT(evt);
|
| - return this->onQuery(evt);
|
| -}
|
| -
|
| -bool SkEventSink::onEvent(const SkEvent&)
|
| -{
|
| - return false;
|
| -}
|
| -
|
| -bool SkEventSink::onQuery(SkEvent*)
|
| -{
|
| - return false;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -SkTagList* SkEventSink::findTagList(U8CPU tag) const
|
| -{
|
| - return fTagHead ? SkTagList::Find(fTagHead, tag) : NULL;
|
| -}
|
| -
|
| -void SkEventSink::addTagList(SkTagList* rec)
|
| -{
|
| - SkASSERT(rec);
|
| - SkASSERT(fTagHead == NULL || SkTagList::Find(fTagHead, rec->fTag) == NULL);
|
| -
|
| - rec->fNext = fTagHead;
|
| - fTagHead = rec;
|
| -}
|
| -
|
| -void SkEventSink::removeTagList(U8CPU tag)
|
| -{
|
| - if (fTagHead)
|
| - SkTagList::DeleteTag(&fTagHead, tag);
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -struct SkListenersTagList : SkTagList {
|
| - SkListenersTagList(U16CPU count) : SkTagList(kListeners_SkTagList)
|
| - {
|
| - fExtra16 = SkToU16(count);
|
| - fIDs = (SkEventSinkID*)sk_malloc_throw(count * sizeof(SkEventSinkID));
|
| - }
|
| - virtual ~SkListenersTagList()
|
| - {
|
| - sk_free(fIDs);
|
| - }
|
| -
|
| - int countListners() const { return fExtra16; }
|
| -
|
| - int find(SkEventSinkID id) const
|
| - {
|
| - const SkEventSinkID* idptr = fIDs;
|
| - for (int i = fExtra16 - 1; i >= 0; --i)
|
| - if (idptr[i] == id)
|
| - return i;
|
| - return -1;
|
| - }
|
| -
|
| - SkEventSinkID* fIDs;
|
| -};
|
| -
|
| -void SkEventSink::addListenerID(SkEventSinkID id)
|
| -{
|
| - if (id == 0)
|
| - return;
|
| -
|
| - SkListenersTagList* prev = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
|
| - int count = 0;
|
| -
|
| - if (prev)
|
| - {
|
| - if (prev->find(id) >= 0)
|
| - return;
|
| - count = prev->countListners();
|
| - }
|
| -
|
| - SkListenersTagList* next = SkNEW_ARGS(SkListenersTagList, (count + 1));
|
| -
|
| - if (prev)
|
| - {
|
| - memcpy(next->fIDs, prev->fIDs, count * sizeof(SkEventSinkID));
|
| - this->removeTagList(kListeners_SkTagList);
|
| - }
|
| - next->fIDs[count] = id;
|
| - this->addTagList(next);
|
| -}
|
| -
|
| -void SkEventSink::copyListeners(const SkEventSink& sink)
|
| -{
|
| - SkListenersTagList* sinkList = (SkListenersTagList*)sink.findTagList(kListeners_SkTagList);
|
| - if (sinkList == NULL)
|
| - return;
|
| - SkASSERT(sinkList->countListners() > 0);
|
| - const SkEventSinkID* iter = sinkList->fIDs;
|
| - const SkEventSinkID* stop = iter + sinkList->countListners();
|
| - while (iter < stop)
|
| - addListenerID(*iter++);
|
| -}
|
| -
|
| -void SkEventSink::removeListenerID(SkEventSinkID id)
|
| -{
|
| - if (id == 0)
|
| - return;
|
| -
|
| - SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
|
| -
|
| - if (list == NULL)
|
| - return;
|
| -
|
| - int index = list->find(id);
|
| - if (index >= 0)
|
| - {
|
| - int count = list->countListners();
|
| - SkASSERT(count > 0);
|
| - if (count == 1)
|
| - this->removeTagList(kListeners_SkTagList);
|
| - else
|
| - {
|
| - // overwrite without resize/reallocating our struct (for speed)
|
| - list->fIDs[index] = list->fIDs[count - 1];
|
| - list->fExtra16 = SkToU16(count - 1);
|
| - }
|
| - }
|
| -}
|
| -
|
| -bool SkEventSink::hasListeners() const
|
| -{
|
| - return this->findTagList(kListeners_SkTagList) != NULL;
|
| -}
|
| -
|
| -void SkEventSink::postToListeners(const SkEvent& evt, SkMSec delay)
|
| -{
|
| - SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
|
| - if (list)
|
| - {
|
| - SkASSERT(list->countListners() > 0);
|
| - const SkEventSinkID* iter = list->fIDs;
|
| - const SkEventSinkID* stop = iter + list->countListners();
|
| - while (iter < stop)
|
| - (SkNEW_ARGS(SkEvent, (evt)))->post(*iter++, delay);
|
| - }
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -SkEventSink::EventResult SkEventSink::DoEvent(const SkEvent& evt, SkEventSinkID sinkID)
|
| -{
|
| - SkEventSink* sink = SkEventSink::FindSink(sinkID);
|
| -
|
| - if (sink)
|
| - {
|
| -#ifdef SK_DEBUG
|
| - if (evt.isDebugTrace())
|
| - {
|
| - SkString etype;
|
| - evt.getType(&etype);
|
| - SkDebugf("SkEventTrace: dispatching event <%s> to 0x%x", etype.c_str(), sinkID);
|
| - const char* idStr = evt.findString("id");
|
| - if (idStr)
|
| - SkDebugf(" (%s)", idStr);
|
| - SkDebugf("\n");
|
| - }
|
| -#endif
|
| - return sink->doEvent(evt) ? kHandled_EventResult : kNotHandled_EventResult;
|
| - }
|
| - else
|
| - {
|
| -#ifdef SK_DEBUG
|
| - if (sinkID)
|
| - SkDebugf("DoEvent: Can't find sink for ID(%x)\n", sinkID);
|
| - else
|
| - SkDebugf("Event sent to 0 sinkID\n");
|
| -
|
| - if (evt.isDebugTrace())
|
| - {
|
| - SkString etype;
|
| - evt.getType(&etype);
|
| - SkDebugf("SkEventTrace: eventsink not found <%s> for 0x%x\n", etype.c_str(), sinkID);
|
| - }
|
| -#endif
|
| - return kSinkNotFound_EventResult;
|
| - }
|
| -}
|
| -
|
| -SkEventSink* SkEventSink::FindSink(SkEventSinkID sinkID)
|
| -{
|
| - if (sinkID == 0)
|
| - return 0;
|
| -
|
| - SkEventSink_Globals& globals = *(SkEventSink_Globals*)SkGlobals::Find(SK_EventSink_GlobalsTag, create_globals);
|
| - SkAutoMutexAcquire ac(globals.fSinkMutex);
|
| - SkEventSink* sink = globals.fSinkHead;
|
| -
|
| - while (sink)
|
| - {
|
| - if (sink->getSinkID() == sinkID)
|
| - return sink;
|
| - sink = sink->fNextSink;
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////////////
|
| -////////////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -#if 0 // experimental, not tested
|
| -
|
| -#include "SkThread.h"
|
| -#include "SkTDict.h"
|
| -
|
| -#define kMinStringBufferSize 128
|
| -static SkMutex gNamedSinkMutex;
|
| -static SkTDict<SkEventSinkID> gNamedSinkIDs(kMinStringBufferSize);
|
| -
|
| -/** Register a name/id pair with the system. If the name already exists,
|
| - replace its ID with the new id. This pair will persist until UnregisterNamedSink()
|
| - is called.
|
| -*/
|
| -void SkEventSink::RegisterNamedSinkID(const char name[], SkEventSinkID id)
|
| -{
|
| - if (id && name && *name)
|
| - {
|
| - SkAutoMutexAcquire ac(gNamedSinkMutex);
|
| - gNamedSinkIDs.set(name, id);
|
| - }
|
| -}
|
| -
|
| -/** Return the id that matches the specified name (from a previous call to
|
| - RegisterNamedSinkID(). If no match is found, return 0
|
| -*/
|
| -SkEventSinkID SkEventSink::FindNamedSinkID(const char name[])
|
| -{
|
| - SkEventSinkID id = 0;
|
| -
|
| - if (name && *name)
|
| - {
|
| - SkAutoMutexAcquire ac(gNamedSinkMutex);
|
| - (void)gNamedSinkIDs.find(name, &id);
|
| - }
|
| - return id;
|
| -}
|
| -
|
| -/** Remove all name/id pairs from the system. This is call internally
|
| - on shutdown, to ensure no memory leaks. It should not be called
|
| - before shutdown.
|
| -*/
|
| -void SkEventSink::RemoveAllNamedSinkIDs()
|
| -{
|
| - SkAutoMutexAcquire ac(gNamedSinkMutex);
|
| - (void)gNamedSinkIDs.reset();
|
| -}
|
| -#endif
|
|
|