[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

A filter CxObject by itself is not especially useful.  It needs some other
CxObjects attached to it.  A commodity interested in knowing if a specific
key was pressed uses a filter to detect and divert the corresponding
CxMessage down the filter's personal list.  The filter does this without
letting the commodity know what happened.  The sender CxObject can be
attached to a filter to notify a commodity that it received a CxMessage.
CxSender() is a macro that creates a sender CxObject.

    senderCxObj = CxObj *CxSender(struct MsgPort *senderport, LONG cxmID);

CxSender() supplies the sender with an Exec message port and an ID.  For
every CxMessage a sender receives, it sends a new CxMessage to the Exec
message port passed in CxSender().  Normally, the commodity creates this
port.  It is not unusual for a commodity's broker and sender(s) to share
an Exec message port.  The HotKey.c example does this to avoid creating
unnecessary message ports.  A sender uses the ID (cxmID) passed to
CxSender() as the ID for all the CxMessages that the it transmits.  A
commodity uses the ID to monitor CxMessages from several senders at a
single message port.

A sender does several things when it receives a CxMessage.  First, it
duplicates the CxMessage's corresponding input event and creates a new
CxMessage.  Then, it points the new CxMessage's data field to the copy of
the input event and sets the new CxMessage's ID to the ID passed to
CxSender().  Finally, it sends the new CxMessage to the port passed to
CxSender(), asynchronously.

Because HotKey uses only one message port between its broker and sender
object, it has to extract the CxMessage's type so it can tell if it is a
CXM_IEVENT or a CXM_COMMAND.  If HotKey gets a CXM_IEVENT, it compares the
CxMessage's ID to the sender's ID, EVT_HOTKEY, to see which sender sent
the CxMessage.  Of course HotKey has only one sender, so it only checks
for only one ID.  If it had more senders, HotKey would check for the ID of
each of the other senders as well.

Although HotKey doesn't use it, a CXM_IEVENT CxMessage contains a pointer
to the copy of an input event.  A commodity can extract this pointer
( using CxMsgData() ) if it needs to examine the input event copy.  This
pointer is only valid before the CxMessage reply.  Note that it does not
make any sense to modify the input event copy.

Senders are attached almost exclusively to CxObjects that filter out most
input events (usually a filter CxObject).  Because a sender sends a
CxMessage for every single input event it gets, it should only get a
select few input events.  The AttachCxObj() function can add a CxObject to
the end of a filter's (or some other filtering CxObject's) personal list.
A commodity should not attach a CxObject to a sender as a sender ignores
any CxObjects in its personal list.