;/* mousetest.c - Execute me to compile me with SAS C 5.10
LC -b1 -cfistq -v -y -j73 mousetest.c
Blink FROM LIB:c.o,mousetest.o TO mousetest LIBRARY LIB:LC.lib,LIB:Amiga.lib
quit
** mousetest.c - Read position and button events from the mouse.
*/
#define INTUI_V36_NAMES_ONLY
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#include <devices/inputevent.h>
#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <stdio.h>
#ifdef LATTICE
int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */
int chkabort(void) { return(0); } /* really */
#endif
#define BUFSIZE 16
/* something to use to track the time between messages
** to test for double-clicks.
*/
typedef struct myTimeVal
{
ULONG LeftSeconds;
ULONG LeftMicros;
ULONG RightSeconds;
ULONG RightMicros;
} MYTIMEVAL;
/* our function prototypes */
VOID doButtons(struct IntuiMessage *msg, MYTIMEVAL *tv);
VOID process_window(struct Window *win);
struct Library *IntuitionBase;
struct GfxBase *GfxBase; /* we need GfxBase->DefaultFont */
/*
** main() -- set-up everything.
*/
VOID main(int argc, char **argv)
{
struct Window *win;
struct Screen *scr;
struct DrawInfo *dr_info;
ULONG width;
/* Open the libraries we will use. Requires Release 2 (KS V2.04, V37) */
if (IntuitionBase = OpenLibrary("intuition.library",37))
{
if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37))
{
/* Lock the default public screen in order to read its DrawInfo data */
if (scr = LockPubScreen(NULL))
{
if (dr_info = GetScreenDrawInfo(scr))
{
/* use wider of space needed for output (18 chars and spaces)
* or titlebar text plus room for titlebar gads (approx 18 each)
*/
width = max((GfxBase->DefaultFont->tf_XSize * 18),
(18 * 2) + TextLength(&scr->RastPort,"MouseTest",9));
if (win = OpenWindowTags(NULL,
WA_Top, 20,
WA_Left, 100,
WA_InnerWidth, width,
WA_Height, (2 * GfxBase->DefaultFont->tf_YSize) +
scr->WBorTop + scr->Font->ta_YSize + 1 +
scr->WBorBottom,
WA_Flags, WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
WFLG_ACTIVATE | WFLG_REPORTMOUSE |
WFLG_RMBTRAP | WFLG_DRAGBAR,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY |
IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS,
WA_Title, "MouseTest",
WA_PubScreen, scr,
TAG_END))
{
printf("Monitors the Mouse:\n");
printf(" Move Mouse, Click and DoubleClick in Window\n");
SetAPen(win->RPort,dr_info->dri_Pens[TEXTPEN]);
SetBPen(win->RPort,dr_info->dri_Pens[BACKGROUNDPEN]);
SetDrMd(win->RPort,JAM2);
process_window(win);
CloseWindow(win);
}
FreeScreenDrawInfo(scr, dr_info);
}
UnlockPubScreen(NULL,scr);
}
CloseLibrary((struct Library *)GfxBase);
}
CloseLibrary(IntuitionBase);
}
}
/*
** process_window() - simple message loop for processing IntuiMessages
*/
VOID process_window(struct Window *win)
{
USHORT done;
struct IntuiMessage *msg;
MYTIMEVAL tv;
UBYTE prt_buff[14];
LONG xText, yText; /* places to position text in window. */
done = FALSE;
tv.LeftSeconds = 0; /* initial values for testing double-click */
tv.LeftMicros = 0;
tv.RightSeconds = 0;
tv.RightMicros = 0;
xText = win->BorderLeft + (win->IFont->tf_XSize * 2);
yText = win->BorderTop + 3 + win->IFont->tf_Baseline;
while (!done)
{
Wait((1L<<win->UserPort->mp_SigBit));
while ((!done) &&
(msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
{
switch (msg->Class)
{
case IDCMP_CLOSEWINDOW:
done = TRUE;
break;
/* NOTE NOTE NOTE: If the mouse queue backs up a lot, Intuition
** will start dropping MOUSEMOVE messages off the end until the
** queue is serviced. This may cause the program to lose some
** of the MOUSEMOVE events at the end of the stream.
**
** Look in the window structure if you need the true position
** of the mouse pointer at any given time. Look in the
** MOUSEBUTTONS message if you need position when it clicked.
** An alternate to this processing would be to set a flag that
** a mousemove event arrived, then print the position of the
** mouse outside of the "while (GetMsg())" loop. This allows
** a single processing call for many mouse events, which speeds
** up processing A LOT! Something like:
**
** while (GetMsg())
** {
** if (class == IDCMP_MOUSEMOVE)
** mouse_flag = TRUE;
** ReplyMsg(); NOTE: copy out all needed fields first !
** }
** if (mouse_flag)
** {
** process_mouse_event();
** mouse_flag = FALSE;
** }
**
** You can also use IDCMP_INTUITICKS for slower paced messages
** (all messages have mouse coordinates.)
*/
case IDCMP_MOUSEMOVE:
/* Show the current position of the mouse relative to the
** upper left hand corner of our window
*/
Move(win->RPort,xText,yText);
sprintf(prt_buff, "X%5d Y%5d", msg->MouseX, msg->MouseY);
Text(win->RPort,prt_buff,13);
break;
case IDCMP_MOUSEBUTTONS:
doButtons(msg,&tv);
break;
}
ReplyMsg((struct Message *)msg);
}
}
}
/*
** Show what mouse buttons where pushed
*/
VOID doButtons(struct IntuiMessage *msg, MYTIMEVAL *tv)
{
/* Yes, qualifiers can apply to the mouse also. That is how
** we get the shift select on the Workbench. This shows how
** to see if a specific bit is set within the qualifier
*/
if (msg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
printf("Shift ");
switch (msg->Code)
{
case SELECTDOWN:
printf("Left Button Down at X%ld Y%ld", msg->MouseX, msg->MouseY);
if(DoubleClick(tv->LeftSeconds, tv->LeftMicros, msg->Seconds, msg->Micros))
printf(" DoubleClick!");
else
{
tv->LeftSeconds = msg->Seconds;
tv->LeftMicros = msg->Micros;
tv->RightSeconds = 0;
tv->RightMicros = 0;
}
break;
case SELECTUP:
printf("Left Button Up at X%ld Y%ld", msg->MouseX, msg->MouseY);
break;
case MENUDOWN:
printf("Right Button down at X%ld Y%ld", msg->MouseX, msg->MouseY);
if(DoubleClick(tv->RightSeconds, tv->RightMicros, msg->Seconds, msg->Micros))
printf(" DoubleClick!");
else
{
tv->LeftSeconds = 0;
tv->LeftMicros = 0;
tv->RightSeconds = msg->Seconds;
tv->RightMicros = msg->Micros;
}
break;
case MENUUP:
printf("Right Button Up at X%ld Y%ld", msg->MouseX, msg->MouseY);
break;
}
printf("\n");
}
[Back to Amiga Developer Docs]