@trixie
After a few days of absence, I discovered this thread to have grown a few pages with quite some interesting remarks and suggestions.
In the meantime for my further investigation and comprehension of the matter, I took the HotKey.c example from the wiki, made it suitable for OS4 and used it as a testbed for my further experiments. Here's the code:
Code: Select all
/*
** HotKey.c - Simple hot key commodity
*/
#include <exec/libraries.h>
#include <libraries/commodities.h>
#include <dos/dos.h>
#include <proto/exec.h>
#include <proto/commodities.h>
#include <proto/dos.h>
#define EVT_HOTKEY 1L
#define CX_FILTERPATTERN "rawkey control esc"
struct NewBroker newbroker = { NB_VERSION
, "Amiga HotKey"
, "A Simple HotKey"
, "A simple hot key commodity"
, NBU_UNIQUE | NBU_NOTIFY
, 0
, 0
, NULL
, 0
};
int main(int argc, char **argv)
{
IDOS->Printf("INFO : Setup commodity...\n");
/*
** A port is added to struct NewBroker:
*/
newbroker.nb_Port = IExec->AllocSysObject(ASOT_PORT, TAG_END);
if (newbroker.nb_Port != NULL)
{
CxObj *broker = ICommodities->CxBroker(&newbroker, NULL);
/*
** The port's signal number is retrieved
** and used to construct a signal flag:
*/
uint32 cxsigflag = 1L << newbroker.nb_Port->mp_SigBit;
if (broker != NULL)
{
/*
** A filter is set up in order
** to retrieve the input events
** we are looking for, as specified
** in CX_FILTERPATTERN:
*/
CxObj *filter = CxFilter(CX_FILTERPATTERN),
*sender,
*translate;
int32 CxErr;
if (filter != NULL)
{
/*
** The filter is attached to the broker:
*/
ICommodities->AttachCxObj(broker, filter);
/*
** Subsequently a sender is constructed,
** te signal the broker when an inputevent
** has occurred.
** The sender is subsequently attached to
** the filter object:
*/
if (sender = CxSender(newbroker.nb_Port, EVT_HOTKEY))
{
ICommodities->AttachCxObj(filter, sender);
/*
** Finally, a translator object is constructed
** and added to the chain of objects. Translator
** objects should be the last in the chain.
** Giving it a 'NULL'-value makes the translator
** stops the filtered-out inputevents from going
** further through the input event stream, which
** would be of little use:
*/
if (translate = CxTranslate(NULL))
{
ICommodities->AttachCxObj(filter, translate);
CxErr = ICommodities->CxObjError(filter);
if (CxErr == 0)
{
CxMsg *msg;
uint32 msgid,
msgtype,
sigrcvd;
ICommodities->ActivateCxObj(broker, 1L);
BOOL Done = FALSE;
IDOS->Printf("INFO : Here we go...\n");
while (Done == FALSE)
{
sigrcvd = IExec->Wait(SIGBREAKF_CTRL_C | cxsigflag);
while (msg = (CxMsg *)IExec->GetMsg(newbroker.nb_Port))
{
msgid = ICommodities->CxMsgID(msg);
msgtype = ICommodities->CxMsgType(msg);
IExec->ReplyMsg((struct Message *)msg);
switch (msgtype)
{
case CXM_IEVENT:
{
IDOS->Printf("A CXM_EVENT, ");
switch(msgid)
{
case EVT_HOTKEY: /* We got the message from the sender CxObject */
{
IDOS->Printf("You hit the HotKey.\n");
break;
}
default:
{
IDOS->Printf("unknown.\n");
}
}
break;
}
case CXM_COMMAND:
{
IDOS->Printf("A command: ");
switch(msgid)
{
case CXCMD_DISABLE:
{
IDOS->Printf("CXCMD_DISABLE\n");
ICommodities->ActivateCxObj(broker, 0L);
break;
}
case CXCMD_ENABLE:
{
IDOS->Printf("CXCMD_ENABLE\n");
ICommodities->ActivateCxObj(broker, 1L);
break;
}
case CXCMD_KILL:
{
IDOS->Printf("CXCMD_KILL\n");
Done = TRUE;
break;
}
case CXCMD_UNIQUE:
{
IDOS->Printf("CXCMD_UNIQUE\n");
Done = TRUE;
break;
}
default:
{
IDOS->Printf("Unknown msgid\n");
}
}
break;
}
default:
{
IDOS->Printf("Unknown msgtype\n");
}
}
if (sigrcvd & SIGBREAKF_CTRL_C)
{
Done = TRUE;
IDOS->Printf("CTRL C signal break\n");
}
}
}
/*
** Cleanup the list of possible remaining messages from
** the broker's messageport, by replying those messages.
** Failing to do so, MIGHT result in a number of pending
** messages, which will NEVER get an answer and so remain
** in their message queue, thereby just eating memory:
*/
while (msg = (CxMsg *)IExec->GetMsg(newbroker.nb_Port))
{
IExec->ReplyMsg((struct Message *)msg);
}
}
else
{
IDOS->Printf("ERROR: %ld\n", CxErr);
}
}
}
}
ICommodities->DeleteCxObjAll(broker);
}
IExec->FreeSysObject(ASOT_PORT, newbroker.nb_Port);
}
return 0;
}
From the commodities.library I took the following sets of Keywords & Qualifiers:
Code: Select all
CONST_STRPTR KeyWord[] = {"DISKINSERTED"
,"DISKREMOVED"
,"EVENT"
,"NEWPOINTERPOS"
,"NEWPREFS"
,"POINTERPOS"
,"RAWKEY"
,"RAWMOUSE"
,"TIMER"
, NULL
};
CONST_STRPTR Qualifier[] = {"CAPSLOCK"
,"CAPS_LOCK"
,"CONTROL"
,"CTRL"
,"LALT"
,"LAMIGA"
,"LBUTTON"
,"LCOMMAND"
,"LEFTBUTTON"
,"LEFT_ALT"
,"LEFT_AMIGA"
,"LEFT_BUTTON"
,"LEFT_COMMAND"
,"LEFT_SHIFT"
,"LSHIFT"
,"MBUTTON"
,"MIDBUTTON"
,"MIDDLEBUTTON"
,"MIDDLE_BUTTON"
,"NUMERICPAD"
,"NUMERIC_PAD"
,"NUMPAD"
,"NUM_PAD"
,"RALT"
,"RAMIGA"
,"RBUTTON"
,"RCOMMAND"
,"RELATIVEMOUSE"
,"REPEAT"
,"RIGHTBUTTON"
,"RIGHT_ALT"
,"RIGHT_AMIGA"
,"RIGHT_BUTTON"
,"RIGHT_COMMAND"
,"RIGHT_SHIFT"
,"RSHIFT"
,"ALT"
,"CAPS"
,"SHIFT"
,"UPSTROKE"
,"MOUSE_4THPRESS"
,"MOUSE_5THPRESS"
,"MOUSE_LEFTPRESS"
,"MOUSE_MIDDLEPRESS"
,"MOUSE_RIGHTPRESS"
,"BACKSPACE"
,"BREAK"
,"COMMA"
,"CURSOR_DOWN"
,"CURSOR_LEFT"
,"CURSOR_RIGHT"
,"CURSOR_UP"
,"DEL"
,"DELETE"
,"DOWN"
,"END"
,"ENTER"
,"ESC"
,"ESCAPE"
,"F1"
,"F10"
,"F11"
,"F12"
,"F2"
,"F3"
,"F4"
,"F5"
,"F6"
,"F7"
,"F8"
,"F9"
,"HELP"
,"HOME"
,"INSERT"
,"LEFT"
,"MEDIA_NEXT"
,"MEDIA_PLAY"
,"MEDIA_PREV"
,"MEDIA_REPEAT"
,"MEDIA_SHUFFLE"
,"MEDIA_STOP"
,"PAGE_DOWN"
,"PAGE_UP"
,"PAUSE"
,"PRINTSCREEN"
,"RETURN"
,"RIGHT"
,"SPACEBAR"
,"TAB"
,"UP"
, NULL
};
I'll try and have every keyword attach to every qualifier and see whether that produces a viable CxFilter by checking the errorcode it sets.
I enjoyed following this thread and see what and where it has lead to!
OldFart