** eventloop.c - standard technique to handle IntuiMessages from an IDCMP.
/* our function prototypes */
BOOL handleIDCMP(struct Window *win, BOOL done);
struct Library *IntuitionBase = NULL;
struct IntuitionIFace *IIntuition = NULL;
** main routine.
** Open required library and window, then process the events from the
** window. Free all resources when done.
int main(int argc, char **argv)
struct Window *win;
IntuitionBase = IExec->OpenLibrary("intuition.library", 50);
IIntuition = (struct IntuitionIFace *)IExec->GetInterface(IntuitionBase,
"main", 1, NULL);
if (IIntuition != NULL)
if (win = IIntuition->OpenWindowTags(NULL,
WA_Title, "Press Keys and Mouse in this
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY |
IDCMP_RAWKEY | IDCMP_DISKINSERTED |
IDCMP_DISKREMOVED | IDCMP_MOUSEBUTTONS,
done = FALSE;
/* perform this loop until the message handling routine signals
** that we are done.
** When the Wait() returns, check which signal hit and process
** the correct port. There is only one port here, so the test
** could be eliminated. If multiple ports were being watched,
** the test would become:
** signals = Wait( (1L << win1->UserPort->mp_SigBit) |
** (1L << win2->UserPort->mp_SigBit) |
** (1L << win3->UserPort->mp_SigBit))
** if (signals & (1L << win1->UserPort->mp_SigBit))
** done = handleWin1IDCMP(win1,done);
** else if (signals & (1L <<
** done = handleWin2IDCMP(win2,done);
** else if (signals & (1L <<
** done = handleWin3IDCMP(win3,done);
** Note that these could all call the same routine with different
** window pointers (if the handling was identical).
** handleIDCMP() should remove all of the messages from the port.
uint32 signals = IExec->Wait(1L <<
if (signals & (1L << win->UserPort->mp_SigBit))
done = handleIDCMP(win,done);
** handleIDCMP() - handle all of the messages from an IDCMP.
BOOL handleIDCMP(struct Window *win, BOOL done)
struct IntuiMessage *message;
int16 mousex, mousey;
/* Remove all of the messages from the port by calling GetMsg()
** until it returns NULL.
** The code should be able to handle three cases:
** 1. No messages waiting at the port, and the first call to GetMsg()
** returns NULL. In this case the code should do nothing.
** 2. A single message waiting. The code should remove the message,
** processes it, and finish.
** 3. Multiple messages waiting. The code should process each waiting
** message, and finish.
while (NULL != (message = (struct IntuiMessage
/* It is often convenient to copy the data out of the message.
** In many cases, this lets the application reply to the message
** quickly. Copying the data is not required, if the code does
** not reply to the message until the end of the loop, then
** it may directly reference the message information anywhere
** before the reply.
class = message->Class;
code = message->Code;
mousex = message->MouseX;
mousey = message->MouseY;
/* The loop should reply as soon as possible. Note that the code
** may not reference data in the message after replying to the
** message. Thus, the application should not reply to the message
** until it is done referencing information in it.
** Be sure to reply to every message received with GetMsg().
IExec->ReplyMsg((struct Message *)message);
/* The class contains the IDCMP type of the message. */
done = TRUE;
IDOS->Printf("IDCMP_VANILLAKEY (%lc %ld)\\n",code,
/* the code often contains useful data, such as the ASCII
** value (for IDCMP_VANILLAKEY), or the type of button
** event here.
IDOS->Printf("Unknown IDCMP message\\n");