[comp.sys.amiga] DMOUSE 1.09 SHAR

dillon@CORY.BERKELEY.EDU (Matt Dillon) (08/01/88)

	Everything fixed.

	New features added

	Bigger, Better, Larger (not so good) .. the handler is up to a 
    whopping 3832 bytes now.

	+Workaround for WindowToFront()/UpFrontLayer() jiggalo...   Essentially
    you can now select between the two.  You can also set the qualifier for
    the LMB ... so set it to shift and there ain't gonna be no problems
    anymore, right? (pretty please?).

	-don't like LMB/RMB combo on custom screen because the application
    uses it too?  Just change the qualifiers...

					-Matt



#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	Makefile
#	dmouse-handler.c
#	dmouse-handler.uue
#	dmouse.c
#	dmouse.doc
#	dmouse.h
#	dmouse.uue
# This archive created: Mon Aug  1 00:38:14 1988
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'Makefile'" '(393 characters)'
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \!Funky!Stuff! > 'Makefile'

CFLAGS = +L +Icomp:include/symbols.m

SR1 = dmouse.c
SR2 = dmouse-handler.c

OB1 = ram:dmouse.o
OB2 = ram:dmouse-handler.o

EX1 = ram:dmouse
EX2 = ram:dmouse-handler


all:	$(EX1) $(EX2)

$(EX1) : $(OB1)
    ln +Q $(OB1) -lc32 -o $(EX1)

$(EX2) : $(OB2)
    ln +Q $(OB2) -lc32 -o $(EX2)


$(OB1) : $(SR1)
    cc $(CFLAGS) $(SR1) -o $(OB1)

$(OB2) : $(SR2)
    cc $(CFLAGS) $(SR2) -o $(OB2)


!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'dmouse-handler.c'" '(10930 characters)'
if test -f 'dmouse-handler.c'
then
	echo shar: "will not over-write existing file 'dmouse-handler.c'"
else
cat << \!Funky!Stuff! > 'dmouse-handler.c'

/*
 *  DMOUSE-HANDLER.C		compile 32 bit integers (+L), c32.lib
 *				AZTEC COMPILATION
 *  28 June 1988
 *
 *  Note on upping the handler process priority.  This is done to cause the
 *  handler task to get CPU before the current input event completes its
 *  processing so intuition calls made by the process are executed before
 *  the event is propogated.  If said intuition calls block, it's ok
 *  because they are not blocking the input handler process.
 */

#include "dmouse.h"

#define IBASE IntuitionBase

DMS	*Dms;
struct IntuitionBase *IntuitionBase;
struct GfxBase	     *GfxBase;
long		     *LayersBase;

NS	Ns = {	0, 0, 64, -1, 1, -1, -1, 0, CUSTOMSCREEN|SCREENQUIET };
IE DummyIE = { 0 };

IE *handler();

short	NRMe;	/*  Don't Repeat Mouse Events   */

_main()
{
    register DMS *dms;
    IOR  *ior;
    INT addhand;

    {
	register PROC *proc = (PROC *)FindTask(NULL);
	proc->pr_ConsoleTask = NULL;
    }
    NRMe = 0;
    dms = Dms = FindPort(PORTNAME);
    if (!dms)
	_exit(0);
    dms->Port.mp_Flags = PA_SIGNAL;
    dms->Port.mp_SigBit = AllocSignal(-1);
    dms->Port.mp_SigTask = FindTask(NULL);
    dms->HandTask = dms->Port.mp_SigTask;
    ior = CreateStdIO(&dms->Port);
    IntuitionBase = OpenLibrary("intuition.library", 0);
    GfxBase = OpenLibrary("graphics.library", 0);
    LayersBase = OpenLibrary("layers.library", 0);

    if (!IntuitionBase || !GfxBase || !LayersBase)
	goto startupfail;
    addhand.is_Node.ln_Pri = dms->IPri;
    addhand.is_Code = (FPTR)handler;
    addhand.is_Data = NULL;

    if (OpenDevice("input.device", 0, ior, 0)) {
	goto startupfail;
    } else {
	SCR *scr = NULL;
	uword *SprSavePtr = NULL;

	Signal(dms->ShakeTask, 1 << dms->ShakeSig);
	ior->io_Command = IND_ADDHANDLER;
	ior->io_Data = (APTR)&addhand;
	ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
	DoIO(ior);
	for (;;) {
	    register long sigs = Wait(SBF_C|(1<<dms->Port.mp_SigBit));
	    if (sigs & (1 << dms->Port.mp_SigBit)) {
		register REQ *msg;
		while (msg = GetMsg(&dms->Port)) {
		    switch((long)msg->Msg.mn_Node.ln_Name) {
		    case REQ_SCREENON:
			if (scr)
			    CloseScreen(scr);
			scr = NULL;
			break;
		    case REQ_SCREENOFF:
			if (scr) {
			    ScreenToFront(scr);
			} else {
			    if (scr = OpenScreen(&Ns))
				SetRGB4(&scr->ViewPort, 0, 0, 0, 0);
			}
			break;
		    case REQ_MOUSEON:
			if (SprSavePtr) {
			    register COPINIT *ci = GfxBase->copinit;
			    ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
			    ci->sprstrtup[3] = (uword)(long)SprSavePtr;
			    SprSavePtr = NULL;
			}
			break;
		    case REQ_MOUSEOFF:
			{
			    register COPINIT *ci = GfxBase->copinit;
			    if (!SprSavePtr)
				SprSavePtr = (uword *)((ci->sprstrtup[1] << 16) | ci->sprstrtup[3]);
			    ci->sprstrtup[1] = (ulong)dms->NoSprData >> 16;
			    ci->sprstrtup[3] = (uword)(long)dms->NoSprData;
			}
			break;
		    case REQ_DOCMD:
			{
			    long fh = Open("nil:", 1006);
			    Execute(dms->Cmd, NULL, fh);
			    if (fh)
				Close(fh);
			}
			break;
		    case REQ_RAWMOUSE:
			{
			    register LAYER *layer;

			    NRMe = 0;
			    Forbid();
			    layer = WhichMouseLayer();
			    if (msg->ie_Code == IECODE_RBUTTON && dms->LMBEnable && (msg->ie_Qualifier & dms->RQual)) {
				register WIN *win;
				if (layer && (win = (WIN *)layer->Window) && !(win->Flags & BACKDROP) && (win->NextWindow || win->WScreen->FirstWindow != win)) {
				    if (dms->Workbench)
					WindowToBack(win);
				    else
					BehindLayer(0, layer);
				} else if (IBASE->FirstScreen)
				    ScreenToBack(IBASE->FirstScreen);
			    }
			    if (layer && layer->Window) {
				if (msg->ie_Code == IECODE_LBUTTON && !(((WIN *)layer->Window)->Flags & BACKDROP) && dms->LMBEnable && layer->ClipRect && layer->ClipRect->Next) {
				    /*
				     *	Note: Case where it is the 'first' click in a series, where dms->CTime is
				     *	      garbage, works properly no matter what DoubleClick returns.
				     */
				    if (dms->LQual == 0 || (msg->ie_Qualifier & dms->LQual)) {
					if ((APTR)dms->CWin == layer->Window && DoubleClick(dms->CTime.tv_secs, dms->CTime.tv_micro, msg->ie_TimeStamp.tv_secs, msg->ie_TimeStamp.tv_micro))
					    --dms->CLeft;
					else
					    dms->CLeft = dms->Clicks - 1;
					dms->CTime = msg->ie_TimeStamp;
					dms->CWin = (WIN *)layer->Window;
					if (dms->CLeft == 0) {
					    dms->CLeft = dms->Clicks;
					    if (dms->Workbench)
						WindowToFront(layer->Window);
					    else
						UpfrontLayer(0, layer);
					}
				    }
				}
				if (dms->AAEnable && layer->Window != IBASE->ActiveWindow && msg->ie_Code == IECODE_NOBUTTON && !(msg->ie_Qualifier & 0x7000))
				    ActivateWindow(layer->Window);
			    }
			    Permit();
			}
			break;
		    case REQ_RAWKEY:
			{
			    register LAYER *layer;

			    Forbid();
			    layer = WhichMouseLayer();
			    if (layer && layer->Window && layer->Window != IBASE->ActiveWindow)
				ActivateWindow(layer->Window);
			    Permit();
			}
			break;
		    }
		    FreeMem(msg, msg->Msg.mn_Length);
		}
	    }
	    if (sigs & SBF_C)
		break;
	}
	ior->io_Command = IND_REMHANDLER;
	ior->io_Data = (APTR)&addhand;
	ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
	DoIO(ior);
	ior->io_Command = IND_WRITEEVENT;	/*  NULL EVENT	*/
	ior->io_Length = sizeof(IE);
	ior->io_Data = (APTR)&DummyIE;
	ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
	DoIO(ior);
	CloseDevice(ior);
	{
	    register MSG *msg;
	    while (msg = GetMsg(&dms->Port))
		FreeMem(msg, msg->mn_Length);
	}
	if (scr)
	    CloseScreen(scr);
	if (SprSavePtr) {
	    register COPINIT *ci = GfxBase->copinit;
	    ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
	    ci->sprstrtup[3] = (uword)(long)SprSavePtr;
	    SprSavePtr = NULL;
	}
    }
    goto closedown;
startupfail:
    dms->StartupError = 1;
    Signal(dms->ShakeTask, 1 << dms->ShakeSig);
    Wait(SBF_C);
closedown:
    DeleteStdIO(ior);
fail:
    if (IntuitionBase)
	CloseLibrary(IntuitionBase);
    if (GfxBase)
	CloseLibrary(GfxBase);
    if (LayersBase)
	CloseLibrary(LayersBase);
    Forbid();
    Signal(dms->ShakeTask, 1 << dms->ShakeSig);
}


#asm
	    ;	A0 = pointer to event linked list
	    ;	A1 = pointer to my data segment
	    ;	return new event linked list in D0

	    public  _CHandler

_handler:
	    movem.l D2/D3/A0/A1/A4/A6,-(sp)
	    jsr     _CHandler
	    movem.l (sp)+,D2/D3/A0/A1/A4/A6
	    rts

#endasm

/*
 *  (1) Accellerate mouse movements.
 *  (2) Auto-Select window
 */

IE *
CHandler(scr0, scr1, Ev)
IE *Ev;
{
    register IE *ev;
    register DMS *dms;
    static char STimedout;
    static char MTimedout;
    static long STime, MTime;

    geta4();
    dms = Dms;
    for (ev = Ev; ev; ev = Ev->ie_NextEvent) {
	switch(ev->ie_Class) {
	case IECLASS_RAWMOUSE:
	    /*
	     *	Mouse events restore both the screen and mouse pointer.
	     */

	    STime = ev->ie_TimeStamp.tv_secs + dms->STo;
	    MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
	    if (STimedout)
		sendrequest(REQ_SCREENON, ev);
	    if (MTimedout)
		sendrequest(REQ_MOUSEON, ev);
	    STimedout = MTimedout = 0;

	    /*
	     *	Mouse Acceleration
	     */
	    {
		register short n;
		register short s;

		if (dms->Acc != 1) {
		    n = ev->ie_X;
		    s = 1;
		    if (n < 0) {
			n = -n;
			s = -1;
		    }
		    if (n > dms->AThresh)
			ev->ie_X = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
		    n = ev->ie_Y;
		    s = 1;
		    if (n < 0) {
			n = -n;
			s = -1;
		    }
		    if (n > dms->AThresh)
			ev->ie_Y = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
		}
	    }

	    /*
	     *	Auto Activate and LMB (win/scrn front/bak)
	     */

	    if (dms->LMBEnable && ev->ie_Code == IECODE_RBUTTON && (ev->ie_Qualifier & dms->RQual))
		ev->ie_Class = IECLASS_NULL;	/*  remove event    */
	    if (NRMe == 0 && ((dms->AAEnable & 1) || dms->LMBEnable)) {
		register short old;
		NRMe = 1;
		if (ev->ie_Code != IECODE_NOBUTTON)
		    old = SetTaskPri(dms->Port.mp_SigTask, 21);
		sendrequest(REQ_RAWMOUSE, ev);
		if (ev->ie_Code != IECODE_NOBUTTON)
		    SetTaskPri(dms->Port.mp_SigTask, old);
	    }
	    break;
	case IECLASS_RAWKEY:
	    /*
	     *	Keyboard events will kill the screen timeout but not
	     *	the mouse timeout.  Note that the priority of the
	     *	co-process must be upped to ensure it is able to make the
	     *	window active before the keystroke is passed further.
	     */

	    if (dms->AAEnable & 2) {
		register short old = SetTaskPri(dms->Port.mp_SigTask, 21);
		sendrequest(REQ_RAWKEY, ev);
		SetTaskPri(dms->Port.mp_SigTask, old);
	    }
	    STime = ev->ie_TimeStamp.tv_secs + dms->STo;
	    if (STimedout) {
		sendrequest(REQ_SCREENON, ev);
		if (dms->MTo == 0)
		    sendrequest(REQ_MOUSEON, ev);
	    }
	    STimedout = 0;
	    if (ev->ie_Code == dms->Code && ev->ie_Qualifier == dms->Qual) {
		sendrequest(REQ_DOCMD, ev);
		ev->ie_Class = IECLASS_NULL;	/*  remove event    */
	    }
	    break;
	case IECLASS_TIMER:
	    /*
	     *	On a timer event, if timeout has occured execute the operation
	     *	and reset the timeout.	Note that this will cause continuous
	     *	timeouts every STo and MTo seconds... required because at any
	     *	time Intuition might turn the mouse back on or open a screen or
	     *	something and I want the blanker's to work in the long run.
	     */
	    {
		register long old;
		if (dms->Reset) {
		    dms->Reset = 0;
		    STime = ev->ie_TimeStamp.tv_secs + dms->STo;
		    MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
		}
		if (dms->STo && (old = STime - ev->ie_TimeStamp.tv_secs) < 0) {
		    STime = ev->ie_TimeStamp.tv_secs + dms->STo + 10;
		    STimedout = 1;
		    MTimedout = 1;
		    if (old > -10) {
			sendrequest(REQ_SCREENOFF, ev);
			sendrequest(REQ_MOUSEOFF, ev);
		    }
		}
		if (dms->MTo && (old = MTime - ev->ie_TimeStamp.tv_secs) < 0) {
		    MTime = ev->ie_TimeStamp.tv_secs + dms->MTo + 1;
		    MTimedout = 1;
		    if (old > -10)
			sendrequest(REQ_MOUSEOFF, ev);
		}
	    }
	    break;
	}
    }
    return(Ev);
}

sendrequest(creq, ev)
long creq;
register IE *ev;
{
    register REQ *req = AllocMem(sizeof(REQ), MEMF_PUBLIC);

    if (req) {
	req->Msg.mn_Node.ln_Name = (char *)creq;
	req->Msg.mn_ReplyPort = NULL;
	req->Msg.mn_Length = sizeof(REQ);
	req->ie_Code = ev->ie_Code;
	req->ie_Qualifier = ev->ie_Qualifier;
	req->ie_TimeStamp = ev->ie_TimeStamp;
	PutMsg(&Dms->Port, req);
    }
}

LAYER *
WhichMouseLayer()
{
    register struct IntuitionBase *ib = IBASE;
    register LAYER *layer = NULL;
    register SCR *scr = ib->FirstScreen;

    for (scr = ib->FirstScreen; scr; scr = scr->NextScreen) {
	register short mousey = ib->MouseY;
	register short mousex = ib->MouseX;
	if (!(scr->ViewPort.Modes & LACE))
	    mousey >>= 1;
	if (!(scr->ViewPort.Modes & HIRES))
	    mousex >>= 1;
	if (layer = WhichLayer(&scr->LayerInfo, mousex, mousey - scr->ViewPort.DyOffset))
	    break;
	if (mousey >= scr->ViewPort.DyOffset)
	    break;
    }
    return(layer);
}


!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'dmouse-handler.uue'" '(5315 characters)'
if test -f 'dmouse-handler.uue'
then
	echo shar: "will not over-write existing file 'dmouse-handler.uue'"
else
cat << \!Funky!Stuff! > 'dmouse-handler.uue'
begin 644 dmouse-handler
M```#\P`````````#``````````(```.8````*@````$```/I```#F$[Z";1.
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
M*@````````/R```#Z@```!```````$#__P`!__\```$/````````````````
M````````````````````````````````````%``````````````#\@```^L`
'```!```#\@``
`
end
!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'dmouse.c'" '(6443 characters)'
if test -f 'dmouse.c'
then
	echo shar: "will not over-write existing file 'dmouse.c'"
else
cat << \!Funky!Stuff! > 'dmouse.c'

/*
 *  DMOUSE.C	V1.09  31 July 1988	(Aztec Compile, +L  ... 32 bit ints)
 *					 and link w/ c32.lib
 *
 *  DMOUSE QUIT
 *  DMOUSE -a# -t# -s# -m# -c# -p# -w# -Ln -lqqqq -Rqqqq -An -Kcccc -Qqqqq -C cmd
 *
 *  -a#     # = acceleration, default 3.	1 to disable
 *  -t#     # = mouse threshold before acceleration takes effect, def. 0
 *		(in pixels/event)
 *  -s#     # = screen timeout, default 5min,	0 to disable
 *  -m#     # = pointer timeout, default 5 secs,0 to disable
 *  -c#     # = # of clicks to bring window to front
 *  -p#     # = input device priority
 *  -w#     1 = Use WindowToFront()/WindowToBack()  else    (workbench users)
 *	    0 = Use UpFrontLayer(), etc...                  (cli users)
 *  -L0     Disable LeftMouseButton->WindowToFront (LMB+RMB->ToBack)
 *  -L1     Enable it
 *  -lqqqq  Set qualifier + LMB for Window to front (default none)
 *  -Rqqqq  Set qualifier + RMB for Window/ScreenToBack (default LMB)
 *  -A0     Disable Auto-Activate window on mouse move
 *  -A1     Enable it, keyhit-auto-activate disabled	(bit 0 = mouse aa)
 *  -A3     Enable it, keyhit-auto-activate enabled	(bit 1 = key aa)
 *  -Kcccc  Set key code in hex that activates cmd, def is escape
 *  -Qqqqq  Set key qualifier in hex for keycode, def is left-amiga
 *  -C cmd  Set command (must be last option on command line), def NewCli
 */

#include <stdio.h>
#include "dmouse.h"

#define VERSION 9

int	Enable_Abort;	    /*	CLI break enable	*/

main(ac, av)
char *av[];
{
    register short i, j, len;
    register long val;
    register char *ptr;
    register DMS  *dms = FindPort(PORTNAME);
    short   exists = (dms != NULL);
    short   create = (dms == NULL);
    short   quit = 0;

    Enable_Abort = 0;
    if (create) {
	dms = AllocMem(sizeof(DMS), MEMF_PUBLIC|MEMF_CLEAR);
	dms->IPri = 51;
	dms->Version = VERSION;
	dms->Acc = 3;
	dms->STo = 5*60;
	dms->MTo = 5;
	dms->Code = 0x45;
	dms->Qual = 0x8040;
	dms->RQual= 0x4000;
	dms->Clicks = 1;
	dms->CLeft = dms->Clicks;
	strcpy(dms->Cmd, "newcli");
	dms->LMBEnable = 1;
	dms->AAEnable = 3;
	dms->NoSprData = AllocMem(12, MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
	dms->NoSprData[0] = 0xFE00;
	dms->NoSprData[1] = 0xFF00;
    }

    for (i = 1; i < ac; ++i) {
	ptr = av[i];
	if (strcmp(ptr, "QUIT") == 0 || strcmp(ptr, "quit") == 0) {
	    quit = 1;
	    create = 0;
	    break;
	}
	val = atoi(ptr+2);
	if (*ptr != '-')
	    goto def;

	switch(ptr[1]) {
	case 'a':
	    dms->Acc = val;
	    break;
	case 'c':
	    if (val < 1)
		val = 1;
	    dms->Clicks = dms->CLeft = val;
	    break;
	case 'w':
	    dms->Workbench = val;
	    break;
	case 'p':
	    dms->IPri = val;
	    break;
	case 't':
	    dms->AThresh = val;
	    break;
	case 's':
	    dms->STo = val;
	    break;
	case 'm':
	    dms->MTo = val;
	    break;
	case 'L':
	    dms->LMBEnable = val;
	    break;
	case 'l':
	    dms->LQual = ahtoi(ptr+2);
	    break;
	case 'R':
	    dms->RQual = ahtoi(ptr+2);
	    break;
	case 'A':
	    dms->AAEnable = val;
	    break;
	case 'K':
	    dms->Code = ahtoi(ptr+2);
	    break;
	case 'Q':
	    dms->Qual = ahtoi(ptr+2) | 0x8000;
	    break;
	case 'C':
	    for (len = strlen(ptr+2) + 2, j = i + 1; j < ac; ++j)
		len += strlen(av[j]) + 1;
	    strcpy(dms->Cmd, ptr + 2);
	    for (j = i + 1; j < ac; ++j) {
		if (dms->Cmd[0])
		    strcat(dms->Cmd, " ");
		strcat(dms->Cmd, av[j]);
	    }
	    i = ac;
	    break;
	default:    def:
	    puts("DMOUSE QUIT  or");
	    puts("DMOUSE -a# -t# -s# -m# -Ln -Rqqqq -An -Kcccc -Qqqqq -C cmd");
	    printf("V1.%02d PUBLIC DOMAIN, Matthew Dillon, 28 June 1988\n\n", VERSION);
	    puts("  -a#     Acceleration (default 3)");
	    puts("  -t#     Accel. threshold (default 0)");
	    puts("  -s#     Screen timeout (default 300)");
	    puts("  -m#     Mouse timeout (default 5)");
	    puts("  -c#     Set # of clicks for wintofront (default 1)");
	    puts("  -p#     # = input device priority");
	    puts("  -w#     0 = use UpFrontLayer().. 1 = use WindowToFront()");
	    puts("  -L0/1   LMB disable/enable (default 1=enabled)");
	    puts("  -lqqqq  LMB qualifier wintofront (default 0=none)");
	    puts("  -Rqqqq  RMB qualifier wintoback (default 4000=LMB)");
	    puts("  -A0-3   Auto-Activate Window disable/enable. B0=mouse B1=keyboard");
	    puts("  -Kcccc  Command Key Code, default 45 = esc");
	    puts("  -Qqqqq  Command Key Qualifier, default 40 = Left Amiga");
	    puts("  -C cmd  cmd to run, must be last option");
	    puts("Note: LMB(or -R qualifier)(hold)+RMB = WindowToBack");
	    puts("\n");
	    puts("Additionaly, Most options may be modified while DMOUSE is active");
	    create = 0;
	    i = ac;
	    break;
	}
    }
    dms->Reset = 1;
    if (!exists && create) {
	PROC *proc;
	printf("Installing DMouse, ");
	fflush(stdout);
	dms->Port.mp_Flags = PA_IGNORE;
	dms->Port.mp_Node.ln_Pri = 0;
	dms->Port.mp_Node.ln_Type= NT_MSGPORT;
	dms->Port.mp_Node.ln_Name= AllocMem(sizeof(PORTNAME), MEMF_PUBLIC);
	strcpy(dms->Port.mp_Node.ln_Name, PORTNAME);
	NewList(&dms->Port.mp_MsgList);
	dms->Segment = LoadSeg("l:DMouse-Handler");
	if (!dms->Segment)
	    dms->Segment = LoadSeg("DMouse-Handler");
	if (!dms->Segment) {
	    puts("Unable to find L:DMouse-Handler");
	    FreeMem(dms->Port.mp_Node.ln_Name, sizeof(PORTNAME));
	    create = 0;
	} else {
	    AddPort(&dms->Port);
	    dms->ShakeTask = FindTask(NULL);
	    dms->ShakeSig = AllocSignal(-1);
	    proc = CreateProc(dms->Port.mp_Node.ln_Name, 1, dms->Segment, 4096);
	    Wait(1 << dms->ShakeSig);
	    FreeSignal(dms->ShakeSig);
	    exists = 1;
	    quit = dms->StartupError;
	    if (quit)
		puts("Handler error");
	    else
		printf("ok.  DMouse V1.%02d, by Matthew Dillon.  PUBLIC DOMAIN.\n", VERSION);
	}
    }
    if (quit) {
	if (exists) {
	    printf("Removing, ");
	    fflush(stdout);
	    dms->ShakeTask = FindTask(NULL);
	    dms->ShakeSig = AllocSignal(-1);
	    Signal(dms->HandTask, SBF_C);
	    Wait(1 << dms->ShakeSig);
	    FreeSignal(dms->ShakeSig);
	    RemPort(&dms->Port);
	    FreeMem(dms->Port.mp_Node.ln_Name, sizeof(PORTNAME));
	    UnLoadSeg(dms->Segment);
	    puts("ok");
	}
	exists = 0;
	create = 0;
    }
    if (!exists) {
	FreeMem(dms->NoSprData, 12);
	FreeMem(dms, sizeof(DMS));
    }
}

ahtoi(str)
register char *str;
{
    register long val = 0;
    register char c;
    while (c = *str) {
	val <<= 4;
	if (c >= '0' && c <= '9')
	    val |= (c & 15);
	else
	    val |= (c & 15) + 9;
	++str;
    }
    return(val);
}


!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'dmouse.doc'" '(8648 characters)'
if test -f 'dmouse.doc'
then
	echo shar: "will not over-write existing file 'dmouse.doc'"
else
cat << \!Funky!Stuff! > 'dmouse.doc'

V1.09			   DMOUSE.DOC	       31 Jul 1988

			  Matthew Dillon
			  891 Regal Rd
			  Berkeley, California 94708
			  USA

	WORKBENCH USERS:    PLEASE READ THE REVISION HISTORY FOR V1.09 FOR
SOLUTION TO INTUITION WINDOWTOFRONT() BUG.

	YAIH (Yet Another Input Handler)... nahh, like DMouse better...
for "Dillon's Mouse"???   Placed in PUBLIC DOMAIN because it's such a
nifty program!

	After looking at and rejecting several mouse-intuition input
handler enhancers (you know, accelerate the mouse, click-to-front, etc...)
and finding them all useless, I have written my own.

	- Any option can be turned off or modified.

	- Screen blanks if keyboard or mouse is idle > N1 secs (def 300)
	    (mouse also blanks even if mouse blanking not turned on)

	- The Pesky Mouse blanks if mouse is idle > N2 secs (def 5)

	- Auto Activate a window when the mouse is moved over it.  Window
	  also activated (if not already active) when you type.  These
	  two features may be turned on/off independantly

	- Mouse Accelerator.  Back feeds power into the mouse unit;
	  give it a nudge and it is guarenteed to penetrate up to an
	  inch and a half of wall plaster (programmable depth).  Once
	  you start using it, you won't be able to switch back!

	- Programmable command-key and command string ala PopCli, default
	  left-Amiga ESC.

	- Left Mouse Button click in window brings it to the front
	    DOES NOT BRING THE WINDOW TO THE FRONT IF IT IS ALREADY
	    IN THE FRONT.  Other programs would call WindowToFront() on
	    every click, which is horrible if you have a simple-refresh
	    window.  WindowToFront() is NOT called for backdrop windows!

	    The qualifier along with the LMB is now settable with the -l option.

	  # clicks required is settable.

	- Hold LMB, click Right Mouse Button .. Window to Back!  Great
	  for cycling windows.	See next feature for more info.

	  (the qualifier, normally the left mouse button, can be set with
	   the -R option).

	- Same sequence as above, but if there is no window under the
	  current mouse position, there is only one window on the screen,
	  or the window under the mouse is a BACKDROP window, the
	  sequence cycles through Screens!

	- NO DAMN CLOCK.  Use another utility to get a clock.  No other
	  glossy thrills.  DMouse is short, sweet, and functional.

	- Does not use a CLI, can be placed in workbench startup sequence.
	  DO NOT 'RUN' DMOUSE!

INSTALLATION:

    Place dmouse-handler in L: (or in the 'current' directory when DMOUSE
    is run).

    WORKBENCH USERS!!!!!!!!!!	There appears to be a bug in intuition's
    WindowToFront() call, which can lock up intuition when workbench
    icons are active.  Under the defaults, this will occur whenever you
    depress the left mouse button over an icon.

    A partial fix is in place V1.07 and beyond.  However, if you find
    it still freezing up, the problem can be avoided as follows:  Either
    turn off the left-mouse-button window- to-front feature (-L0) or leave
    it on and set the number of clicks required to 2 (-c2) (and don't use
    the feature while your mouse is over an icon).  V1.09 gives you yet
    a THIRD option which is even more preferable ... change the qualifier
    that goes along with the left mouse button to something other than 0,
    like 3 (either shift). -l3


EXECUTE FROM A CLI (e.g. WORKBENCH STARTUP SCRIPT), example:

    1> DMouse -C newcli "<nil: >nil: con:320/120/320/80/Shell c:shell.exe"

    There is no need to 'RUN' DMouse.  A double set of quotes may be
    required for the program to work properly with ConMan.

    NOTE:   Your script in c:shell.exe should prefix all commands with a
	    full path or the boot drive (usually DF0:) will be accessed,
	    causing a requestor to appear if no disk is inserted.


TO KILL:

    1> dmouse QUIT

SOURCE:

    Source is compileable under Aztec, +L (32 bit ints) and suitable
    precompiled include file (remember the precompiled include file must
    be precompiled with +L also).  Use the c32.lib library (Aztec C)

    Precompiled include files:	All amiga includes that are in
    sub-directories (i.e. */*.h, but not things like <stdio.h>)


COMMAND LINE ARGUMENTS:

    If DMouse is already running, any specified options will be
    incorporated.

    quit	QUIT .. remove DMouse
    -h		HELP
    -a# 	Set acceleration to #.	Default 3,	     1 disables option
    -t# 	Set mouse acceleration threshhold, pixs/ev. default 0.
    -s# 	Set screen timeout to # (secs), Default 300, 0 disables option
    -m# 	Set mouse timeout to # (secs), Defalut 5,    0 disabled option
    -c# 	Set # of clicks required to bring window to front (def 1)
    -p# 	Set input handler priority (def 51) should always be > 50
		(initial invocation only)

    -w# 	0 = use UpFrontLayer() etc... 1 = use WindowToFront() etc...
		WindowToFront() properly refreshes SIMPLE_REFRESH windows
		but a bug intuition can cause it to crash the machine if
		a workbench icon is active at the time.

    -L0/1	Disable/Enable left-button brings window to front
    -A0-3	Disable/Enable AUTO-ACTIVATE. Bit #0 = mouse auto-activate
						  #1 = keyboard auto-activate
		    (default 3, which enables both)

    -lqqqq	Set Qualifier (HEX) with LMB for Window To Front (default is
		 0, meaning no qualifier).  Example:	-l0003 sets it to
		 either shift key.

    -Rqqqq	Set Qualifier (HEX) with RMB for Window To Back (default is
		 the LMB qualifier).  Setting the qualifier to 0 disables
		 the feature.

    -Kcccc	Set Keycode (HEX)   for command key (default 0045)

    -Qqqqq	Set Qualifier (HEX) for command key (default 0040)

    -C CMD	Set Command to run.  Default is NEWCLI.  Remaining arguments
		on command line is the command.


			QUALIFIERS (always entered in HEX)

    0001    Left Shift
    0002    Right Shift
    0004    Caps Lock
    0008    Control
    0010    Left Alt
    0020    Right Alt
    0040    Left Amiga Key
    0080    Right Amiga Key
    0100    Numeric Key Pad Key (not useful for dmouse)
    0200    Repeat		(not useful for dmouse)
    0400    Interrupt		(not useful for dmouse)
    0800    Multibroadcast	(not useful for dmouse)
    1000    Middle Mouse Button
    2000    Right Mouse Button
    4000    Left Mouse Button

	Note:	Combinations are allowed, in which case any one of the
		selected qualifiers along with the left, right mouse button
		or command key will cause the appropriate action to occur.


RELEASE HISTORY:

V1.09

    Workbench users probably want to use the following options: -w1 -l0003
    These use WindowToFront() (your windows get refreshed properly), but
    also requires you to depress a shift key + LMB to get the window-to-front
    feature.

	dmouse -w1 -l0003

    -SELECTABLE USE OF UpFrontLayer() etc..  OR  WindowToFront() etc...
     Workbench users should use WindowToFront() (-w1), while CLI users
     probably want to use UpFrontLayer() (default).

     Reason:	WindowToFront()/Back can crash the Amiga if called while
     a workbench ICON is highlighted.  Unfortunetly, UpFrontLayer(), which
     does not have the bug, also does not automatically refresh
     simple-refresh windows!

    -New option -lqqqq (SET QUALIFIER WITH LEFT MOUSE BUTTON TO GET
     WINDOW-TO-FRONT FEATURE).	WORKBENCH USERS NOTE:  By setting this
     qualifier to a shift key, for instance, you can safely move icons
     around without crashing the machine because DMouse will not issue
     the WindowToFront() call unless you are holding the qualifier key
     down while pressing the left mouse button.

    -Bug fixed thanks to user persistance!  If you disable mouse blanking,
     and enable screen blanking (which blanks the mouse too when it
     happens), hitting a key would bring back the screen but not the mouse.

V1.08
     Botched.

V1.07
    -All intuition calls are made from an independant process rather than
     the input handler routine.  This also fixes a couple of deadlock bugs,
     but not the workbench-icon deadlock bug.
    -Mouse response is no longer jerky when the system is loaded down.
    -Keyboard-Auto-Activate-Window independant of Mouse-Auto-Activate-Window
     (enhanced -A option)
    -No need to OR the -Q qualifier with 8000 anymore
    -WindowToFront() never called for backdrop windows, which ought to fix
     the workbench freeze bug and other problems.
    -Mouse automatically blanked when screen blanks, whether mouse blanking
     is enabled or not.
    -Can set input handler priority (initial invocation only).
    -New Timeouts go into effect immediately rather than after the
     next mouse/keyboard event.

V1.00-V1.06
    Before Written history


!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'dmouse.h'" '(2278 characters)'
if test -f 'dmouse.h'
then
	echo shar: "will not over-write existing file 'dmouse.h'"
else
cat << \!Funky!Stuff! > 'dmouse.h'

/*
 *  DMOUSE.H
 */

#define DMS struct _DMS
#define REQ struct _REQ

#define PORTNAME    "DMouse"

#define REQ_SCREENON	-1
#define REQ_SCREENOFF	-2
#define REQ_MOUSEON	-3
#define REQ_MOUSEOFF	-4
#define REQ_DOCMD	-5
#define REQ_RAWMOUSE	-6
#define REQ_RAWKEY	-7

#define SBF_C	SIGBREAKF_CTRL_C
#define SBF_D	SIGBREAKF_CTRL_D
#define SBF_E	SIGBREAKF_CTRL_E
#define SBF_F	SIGBREAKF_CTRL_F

typedef unsigned short	    uword;
typedef unsigned long	    ulong;

typedef struct copinit	    COPINIT;
typedef struct Message	    MSG;
typedef struct Custom	    CUST;
typedef struct Preferences  PREFS;
typedef struct InputEvent   IE;
typedef struct MsgPort	    PORT;
typedef struct IOStdReq     IOR;
typedef struct Interrupt    INT;
typedef struct Screen	    SCR;
typedef struct Window	    WIN;
typedef struct Layer	    LAYER;
typedef struct NewScreen    NS;
typedef struct Task	    TASK;
typedef struct Process	    PROC;
typedef struct timeval	    TS;
typedef void		    (*FPTR)();


DMS {
    PORT    Port;
    short   Version;
    short   Acc;
    short   AThresh;
    long    STo;
    long    MTo;
    uword   Code;
    uword   Qual;
    uword   RQual;	    /*	Right button qualifier	*/
    uword   LQual;	    /*	Left button qualifier	*/
    char    Cmd[256];
    char    LMBEnable;
    char    AAEnable;
    char    IPri;
    char    FSEnable;	    /*	Foreign Screen Enable	*/
    char    Workbench;	    /*	Use WindowToFront/Back	*/
    char    Reserved2;
    char    Reserved3;
    TASK    *HandTask;
    TASK    *ShakeTask;
    short   ShakeSig;
    short   StartupError;
    uword   *NoSprData;
    long    Segment;

    uword   Clicks;	/*  # clicks required		*/
    uword   CLeft;	/*  # clicks left to do 	*/
    TS	    CTime;	/*  time of last click		*/
    WIN     *CWin;	/*  All clicks in same window	*/
    char    Reset;	/*  Option modified, reset tos	*/
};

REQ {
    MSG     Msg;
    TS	    ie_TimeStamp;
    uword   ie_Code;
    uword   ie_Qualifier;
};

extern IOR *CreateStdIO();
extern SCR *OpenScreen();
extern void *AllocMem();
extern void *malloc();
extern void *GetMsg();
extern void *OpenLibrary();
extern PORT *CreatePort();
extern TASK *FindTask();
extern PROC *CreateProc();
extern LAYER *WhichMouseLayer();
extern LAYER *WhichLayer();
extern DMS   *FindPort();

!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'dmouse.uue'" '(11329 characters)'
if test -f 'dmouse.uue'
then
	echo shar: "will not over-write existing file 'dmouse.uue'"
else
cat << \!Funky!Stuff! > 'dmouse.uue'
begin 644 dmouse
M```#\P`````````#``````````(```=7````K`````$```/I```'5T[Z"Y!.
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
M:W,@9F]R('=I;G1O9G)O;G0@*&1E9F%U;'0@,2D`("`M<",@("`@(",@/2!I
M;G!U="!D979I8V4@<')I;W)I='D`("`M=R,@("`@(#`@/2!U<V4@57!&<F]N
M=$QA>65R*"DN+B`Q(#T@=7-E(%=I;F1O=U1O1G)O;G0H*0`@("U,,"\Q("`@
M3$U"(&1I<V%B;&4O96YA8FQE("AD969A=6QT(#$]96YA8FQE9"D`("`M;'%Q
M<7$@($Q-0B!Q=6%L:69I97(@=VEN=&]F<F]N="`H9&5F875L="`P/6YO;F4I
M`"`@+5)Q<7%Q("!234(@<75A;&EF:65R('=I;G1O8F%C:R`H9&5F875L="`T
M,#`P/4Q-0BD`("`M03`M,R`@($%U=&\M06-T:79A=&4@5VEN9&]W(&1I<V%B
M;&4O96YA8FQE+B!",#UM;W5S92!",3UK97EB;V%R9``@("U+8V-C8R`@0V]M
M;6%N9"!+97D@0V]D92P@9&5F875L="`T-2`](&5S8P`@("U1<7%Q<2`@0V]M
M;6%N9"!+97D@475A;&EF:65R+"!D969A=6QT(#0P(#T@3&5F="!!;6EG80`@
M("U#(&-M9"`@8VUD('1O(')U;BP@;75S="!B92!L87-T(&]P=&EO;@!.;W1E
M.B!,34(H;W(@+5(@<75A;&EF:65R*2AH;VQD*2M234(@/2!7:6YD;W=4;T)A
M8VL`"@!!9&1I=&EO;F%L>2P@36]S="!O<'1I;VYS(&UA>2!B92!M;V1I9FEE
M9"!W:&EL92!$34]54T4@:7,@86-T:79E`$EN<W1A;&QI;F<@1$UO=7-E+"``
M1$UO=7-E`$1-;W5S90!L.D1-;W5S92U(86YD;&5R`$1-;W5S92U(86YD;&5R
M`%5N86)L92!T;R!F:6YD($PZ1$UO=7-E+4AA;F1L97(`1$UO=7-E`$AA;F1L
M97(@97)R;W(`;VLN("!$36]U<V4@5C$N)3`R9"P@8GD@36%T=&AE=R!$:6QL
M;VXN("!054),24,@1$]-04E.+@H`4F5M;W9I;F<L(`!$36]U<V4`;VL`3E4`
M`$CG#"`D;0`(>``:$F<VZ82Z/``P;1:Z/``Y;A`0!4B`2,#`O`````^(@&`4
M$`5(@$C`P+P````/T+P````)B(!2BF#&(`1,WP0P3EU.=2!O``0@"")O``@0
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
M!$SO((``#"QL@F9.KO^43-\@@$YU3OH``B)O``0L;()F3N[^8B)O``0L;()F
M3N[^GB`O``0L;()F3N[^MD[Z``),[P`#``0L;()F3N[_.B)O``0L;()F3N[^
M>D[Z``(B;P`$+&R"9D[N_MHL;()F3N[_?$[Z``(B;P`$("\`""QL@F9.[O\N
M("\`!"QL@F9.[OZP(&\`!"QL@F9.[OZ,(&\`!""(6)!"J``$(4@`"$YU+&R"
M9B)O``0@+P`(3N[]V")O``0L;()F3N[^F")O``0L;()F3N[^ADSO``,`!"QL
M@F9.[O[.(F\`!"`O``@L;()F3N[^O"`O``0L;()F3N[^PB!O``0L;()F3N[^
M@$SO`P``!"QL@HI.[O^@(&\`!"QL@HI.[O^F(&\`!"QL@HI.[O^R``````/L
M`````0````$```P&`````````_(```/J````EC`Q,C,T-38W.#EA8F-D968`
M```@("`@("`@("`P,#`P,"`@("`@("`@("`@("`@("`@()!`0$!`0$!`0$!`
M0$!`0$`,#`P,#`P,#`P,0$!`0$!`0`D)"0D)"0$!`0$!`0$!`0$!`0$!`0$!
M`0$!0$!`0$!`"@H*"@H*`@("`@("`@("`@("`@("`@("`@)`0$!`(```````
M```````````!``````$``````````````````````0$````!````````````
M``````````$"`````0``````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M```````````````````````````````````````````4````````````````
.`_(```/K`````0```_(`
`
end
!Funky!Stuff!
fi  # end of overwriting check
exit 0
#	End of shell archive