;/* HotKey.c - Simple hot key commodity compiled with SASC 5.10
LC -b0 -cfist -v -j73 hotkey.c
Blink FROM LIB:c.o,hotkey.o TO hotkey LIBRARY LIB:LC.lib,LIB:Amiga.lib
quit
*/
#include <exec/libraries.h>
#include <libraries/commodities.h>
#include <dos/dos.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/alib_stdio_protos.h>
#include <clib/commodities_protos.h>
#ifdef LATTICE
int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */
int chkabort(void) { return(0); }
#endif
#define EVT_HOTKEY 1L
void main(int, char **);
void ProcessMsg(void);
struct Library *CxBase, *IconBase;
struct MsgPort *broker_mp;
CxObj *broker, *filter, *sender, *translate;
struct NewBroker newbroker = {
NB_VERSION,
"RKM HotKey", /* string to identify this broker */
"A Simple HotKey",
"A simple hot key commodity",
NBU_UNIQUE | NBU_NOTIFY, /* Don't want any new commodities starting with this name. */
0, 0, 0, 0 /* If someone tries it, let me know */
};
ULONG cxsigflag;
void main(int argc, char **argv)
{
UBYTE *hotkey, **ttypes;
CxMsg *msg;
if (CxBase = OpenLibrary("commodities.library", 37L))
{
/* open the icon.library for the support library */
/* functions, ArgArrayInit() and ArgArrayDone() */
if (IconBase = OpenLibrary("icon.library", 36L))
{
if (broker_mp = CreateMsgPort())
{
newbroker.nb_Port = broker_mp;
cxsigflag = 1L << broker_mp->mp_SigBit;
/* ArgArrayInit() is a support library function (from the 2.0 version
* of amiga.lib) that makes it easy to read arguments from either a
* CLI or from Workbench's ToolTypes. Because it uses icon.library,
* the library has to be open before calling this function.
* ArgArrayDone() cleans up after this function.
*/
ttypes = ArgArrayInit(argc, argv);
/* ArgInt() (also from amiga.lib) searches through the array set up
* by ArgArrayInit() for a specific ToolType. If it finds one, it
* returns the numeric value of the number that followed the
* ToolType (i.e., CX_PRIORITY=7). If it doesn't find the ToolType,
* it returns the default value (the third argument)
*/
newbroker.nb_Pri = (BYTE)ArgInt(ttypes, "CX_PRIORITY", 0);
/* ArgString() works just like ArgInt(), except it returns a pointer to a string
* rather than an integer. In the example below, if there is no ToolType
* "HOTKEY", the function returns a pointer to "rawkey control esc".
*/
hotkey = ArgString(ttypes, "HOTKEY", "rawkey control esc");
if (broker = CxBroker(&newbroker, NULL))
{
/* CxFilter() is a macro that creates a filter CxObject. This filter
* passes input events that match the string pointed to by hotkey.
*/
if (filter = CxFilter(hotkey))
{
/* Add a CxObject to another's personal list */
AttachCxObj(broker, filter);
/* CxSender() creates a sender CxObject. Every time a sender gets
* a CxMessage, it sends a new CxMessage to the port pointed to in
* the first argument. CxSender()'s second argument will be the ID
* of any CxMessages the sender sends to the port. The data pointer
* associated with the CxMessage will point to a *COPY* of the
* InputEvent structure associated with the orginal CxMessage.
*/
if (sender = CxSender(broker_mp, EVT_HOTKEY))
{
AttachCxObj(filter, sender);
/* CxTranslate() creates a translate CxObject. When a translate
* CxObject gets a CxMessage, it deletes the original CxMessage
* and adds a new input event to the input.device's input stream
* after the Commodities input handler. CxTranslate's argument
* points to an InputEvent structure from which to create the new
* input event. In this example, the pointer is NULL, meaning no
* new event should be introduced, which causes any event that
* reaches this object to disappear from the input stream.
*/
if (translate = (CxTranslate(NULL)))
{
AttachCxObj(filter, translate);
/* CxObjError() is a commodities.library function that returns
* the internal accumulated error code of a CxObject.
*/
if (! CxObjError(filter))
{
ActivateCxObj(broker, 1L);
ProcessMsg();
}
}
}
}
/* DeleteCxObjAll() is a commodities.library function that not only
* deletes the CxObject pointed to in its argument, but it deletes
* all of the CxObjects that are attached to it.
*/
DeleteCxObjAll(broker);
/* Empty the port of all CxMsgs */
while(msg = (CxMsg *)GetMsg(broker_mp))
ReplyMsg((struct Message *)msg);
}
DeletePort(broker_mp);
}
/* this amiga.lib function cleans up after ArgArrayInit() */
ArgArrayDone();
CloseLibrary(IconBase);
}
CloseLibrary(CxBase);
}
}
void ProcessMsg(void)
{
extern struct MsgPort *broker_mp;
extern CxObj *broker;
extern ULONG cxsigflag;
CxMsg *msg;
ULONG sigrcvd, msgid, msgtype;
LONG returnvalue = 1L;
while(returnvalue)
{
sigrcvd = Wait(SIGBREAKF_CTRL_C | cxsigflag);
while(msg = (CxMsg *)GetMsg(broker_mp))
{
msgid = CxMsgID(msg);
msgtype = CxMsgType(msg);
ReplyMsg((struct Message *)msg);
switch(msgtype)
{
case CXM_IEVENT:
printf("A CXM_EVENT, ");
switch(msgid)
{
case EVT_HOTKEY: /* We got the message from the sender CxObject */
printf("You hit the HotKey.\n");
break;
default:
printf("unknown.\n");
break;
}
break;
case CXM_COMMAND:
printf("A command: ");
switch(msgid)
{
case CXCMD_DISABLE:
printf("CXCMD_DISABLE\n");
ActivateCxObj(broker, 0L);
break;
case CXCMD_ENABLE:
printf("CXCMD_ENABLE\n");
ActivateCxObj(broker, 1L);
break;
case CXCMD_KILL:
printf("CXCMD_KILL\n");
returnvalue = 0L;
break;
case CXCMD_UNIQUE:
/* Commodities Exchange can be told not only to refuse to launch a
* commodity with a name already in use but also can notify the
* already running commodity that it happened. It does this by
* sending a CXM_COMMAND with the ID set to CXMCMD_UNIQUE. If the
* user tries to run a windowless commodity that is already running,
* the user wants the commodity to shut down. */
printf("CXCMD_UNIQUE\n");
returnvalue = 0L;
break;
default:
printf("Unknown msgid\n");
break;
}
break;
default:
printf("Unknown msgtype\n");
break;
}
}
if (sigrcvd & SIGBREAKF_CTRL_C)
{
returnvalue = 0L;
printf("CTRL C signal break\n");
}
}
}
[Back to Amiga Developer Docs]