1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkEventSink.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTagList.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkThread.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkThread.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTime.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
179998c669300281b5682fce72b036c1a6a619a44ereed@google.comclass SkEventSink_Globals {
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
199998c669300281b5682fce72b036c1a6a619a44ereed@google.com    SkEventSink_Globals() {
209998c669300281b5682fce72b036c1a6a619a44ereed@google.com        fNextSinkID = 0;
219998c669300281b5682fce72b036c1a6a619a44ereed@google.com        fSinkHead = NULL;
229998c669300281b5682fce72b036c1a6a619a44ereed@google.com    }
239998c669300281b5682fce72b036c1a6a619a44ereed@google.com
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkMutex         fSinkMutex;
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkEventSinkID   fNextSinkID;
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkEventSink*    fSinkHead;
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
299998c669300281b5682fce72b036c1a6a619a44ereed@google.comstatic SkEventSink_Globals& getGlobals() {
309998c669300281b5682fce72b036c1a6a619a44ereed@google.com    // leak this, so we don't incur any shutdown perf hit
319998c669300281b5682fce72b036c1a6a619a44ereed@google.com    static SkEventSink_Globals* gGlobals = new SkEventSink_Globals;
329998c669300281b5682fce72b036c1a6a619a44ereed@google.com    return *gGlobals;
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
359998c669300281b5682fce72b036c1a6a619a44ereed@google.comSkEventSink::SkEventSink() : fTagHead(NULL) {
369998c669300281b5682fce72b036c1a6a619a44ereed@google.com    SkEventSink_Globals& globals = getGlobals();
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    globals.fSinkMutex.acquire();
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fID = ++globals.fNextSinkID;
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fNextSink = globals.fSinkHead;
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    globals.fSinkHead = this;
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    globals.fSinkMutex.release();
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
479998c669300281b5682fce72b036c1a6a619a44ereed@google.comSkEventSink::~SkEventSink() {
489998c669300281b5682fce72b036c1a6a619a44ereed@google.com    SkEventSink_Globals& globals = getGlobals();
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fTagHead)
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkTagList::DeleteAll(fTagHead);
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    globals.fSinkMutex.acquire();
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkEventSink* sink = globals.fSinkHead;
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkEventSink* prev = NULL;
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
589998c669300281b5682fce72b036c1a6a619a44ereed@google.com    for (;;) {
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkEventSink* next = sink->fNextSink;
609998c669300281b5682fce72b036c1a6a619a44ereed@google.com        if (sink == this) {
619998c669300281b5682fce72b036c1a6a619a44ereed@google.com            if (prev) {
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                prev->fNextSink = next;
639998c669300281b5682fce72b036c1a6a619a44ereed@google.com            } else {
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                globals.fSinkHead = next;
659998c669300281b5682fce72b036c1a6a619a44ereed@google.com            }
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        prev = sink;
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sink = next;
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    globals.fSinkMutex.release();
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
749998c669300281b5682fce72b036c1a6a619a44ereed@google.combool SkEventSink::doEvent(const SkEvent& evt) {
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->onEvent(evt);
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
789998c669300281b5682fce72b036c1a6a619a44ereed@google.combool SkEventSink::doQuery(SkEvent* evt) {
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(evt);
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->onQuery(evt);
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
839998c669300281b5682fce72b036c1a6a619a44ereed@google.combool SkEventSink::onEvent(const SkEvent&) {
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return false;
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
879998c669300281b5682fce72b036c1a6a619a44ereed@google.combool SkEventSink::onQuery(SkEvent*) {
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return false;
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
939998c669300281b5682fce72b036c1a6a619a44ereed@google.comSkTagList* SkEventSink::findTagList(U8CPU tag) const {
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fTagHead ? SkTagList::Find(fTagHead, tag) : NULL;
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
979998c669300281b5682fce72b036c1a6a619a44ereed@google.comvoid SkEventSink::addTagList(SkTagList* rec) {
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(rec);
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(fTagHead == NULL || SkTagList::Find(fTagHead, rec->fTag) == NULL);
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    rec->fNext = fTagHead;
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTagHead = rec;
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1059998c669300281b5682fce72b036c1a6a619a44ereed@google.comvoid SkEventSink::removeTagList(U8CPU tag) {
1069998c669300281b5682fce72b036c1a6a619a44ereed@google.com    if (fTagHead) {
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkTagList::DeleteTag(&fTagHead, tag);
1089998c669300281b5682fce72b036c1a6a619a44ereed@google.com    }
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct SkListenersTagList : SkTagList {
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkListenersTagList(U16CPU count) : SkTagList(kListeners_SkTagList)
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fExtra16 = SkToU16(count);
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fIDs = (SkEventSinkID*)sk_malloc_throw(count * sizeof(SkEventSinkID));
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual ~SkListenersTagList()
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_free(fIDs);
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int countListners() const { return fExtra16; }
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int find(SkEventSinkID id) const
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkEventSinkID* idptr = fIDs;
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int i = fExtra16 - 1; i >= 0; --i)
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (idptr[i] == id)
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return i;
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return -1;
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkEventSinkID*  fIDs;
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkEventSink::addListenerID(SkEventSinkID id)
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (id == 0)
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkListenersTagList* prev = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int                 count = 0;
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (prev)
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (prev->find(id) >= 0)
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return;
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        count = prev->countListners();
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkListenersTagList* next = SkNEW_ARGS(SkListenersTagList, (count + 1));
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (prev)
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memcpy(next->fIDs, prev->fIDs, count * sizeof(SkEventSinkID));
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->removeTagList(kListeners_SkTagList);
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    next->fIDs[count] = id;
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->addTagList(next);
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
164d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comvoid SkEventSink::copyListeners(const SkEventSink& sink)
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkListenersTagList* sinkList = (SkListenersTagList*)sink.findTagList(kListeners_SkTagList);
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (sinkList == NULL)
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(sinkList->countListners() > 0);
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkEventSinkID* iter = sinkList->fIDs;
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkEventSinkID* stop = iter + sinkList->countListners();
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (iter < stop)
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        addListenerID(*iter++);
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkEventSink::removeListenerID(SkEventSinkID id)
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (id == 0)
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (list == NULL)
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int index = list->find(id);
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (index >= 0)
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int count = list->countListners();
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count > 0);
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (count == 1)
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->removeTagList(kListeners_SkTagList);
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        else
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        {
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            // overwrite without resize/reallocating our struct (for speed)
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            list->fIDs[index] = list->fIDs[count - 1];
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            list->fExtra16 = SkToU16(count - 1);
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkEventSink::hasListeners() const
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->findTagList(kListeners_SkTagList) != NULL;
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20787fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.comvoid SkEventSink::postToListeners(const SkEvent& evt, SkMSec delay) {
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
20987fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    if (list) {
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(list->countListners() > 0);
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkEventSinkID* iter = list->fIDs;
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkEventSinkID* stop = iter + list->countListners();
21387fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com        while (iter < stop) {
21487fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com            SkEvent* copy = SkNEW_ARGS(SkEvent, (evt));
21587fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com            copy->setTargetID(*iter++)->postDelay(delay);
21687fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com        }
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
22287fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.comSkEventSink::EventResult SkEventSink::DoEvent(const SkEvent& evt) {
22387fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    SkEvent::Proc proc = evt.getTargetProc();
22487fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    if (proc) {
22587fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com        return proc(evt) ? kHandled_EventResult : kNotHandled_EventResult;
22687fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    }
227d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
22887fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    SkEventSink* sink = SkEventSink::FindSink(evt.getTargetID());
22987fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    if (sink) {
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return sink->doEvent(evt) ? kHandled_EventResult : kNotHandled_EventResult;
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
23387fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    return kSinkNotFound_EventResult;
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkEventSink* SkEventSink::FindSink(SkEventSinkID sinkID)
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (sinkID == 0)
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return 0;
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2419998c669300281b5682fce72b036c1a6a619a44ereed@google.com    SkEventSink_Globals&    globals = getGlobals();
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoMutexAcquire      ac(globals.fSinkMutex);
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkEventSink*            sink = globals.fSinkHead;
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (sink)
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (sink->getSinkID() == sinkID)
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return sink;
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sink = sink->fNextSink;
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////////////
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////////////
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0   // experimental, not tested
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkThread.h"
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTDict.h"
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kMinStringBufferSize    128
2631771cbf43d9a1334e3d870c635b4215bb888dd98digit@google.comSK_DECLARE_STATIC_MUTEX(gNamedSinkMutex);
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTDict<SkEventSinkID>   gNamedSinkIDs(kMinStringBufferSize);
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Register a name/id pair with the system. If the name already exists,
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    replace its ID with the new id. This pair will persist until UnregisterNamedSink()
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    is called.
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkEventSink::RegisterNamedSinkID(const char name[], SkEventSinkID id)
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (id && name && *name)
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkAutoMutexAcquire  ac(gNamedSinkMutex);
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gNamedSinkIDs.set(name, id);
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the id that matches the specified name (from a previous call to
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    RegisterNamedSinkID(). If no match is found, return 0
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkEventSinkID SkEventSink::FindNamedSinkID(const char name[])
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkEventSinkID id = 0;
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (name && *name)
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkAutoMutexAcquire  ac(gNamedSinkMutex);
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        (void)gNamedSinkIDs.find(name, &id);
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return id;
2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Remove all name/id pairs from the system. This is call internally
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    on shutdown, to ensure no memory leaks. It should not be called
2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    before shutdown.
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkEventSink::RemoveAllNamedSinkIDs()
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoMutexAcquire  ac(gNamedSinkMutex);
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    (void)gNamedSinkIDs.reset();
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
304