
/*
 *  DMOUSE.C	V1.25  16 December 1990
 *
 *  (c)Copyright 1989 by Matthew Dillon, All Rights Reserved
 *
 *  DMOUSE QUIT
 *  DMOUSE -a# -t# -s# -m# -c# -p# -w# -Ln -lqqqq -Rqqqq -An -Kcccc -Qqqqq -C cmd
 *	   -d#
 *
 *  -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)
 *		NOTE: defaults to -w0 now, will be -w1 for 1.4
 *  -f#     1 = Enable WindowToFront()/Back() (default)
 *	    0 = Disable WindowToFront()/Back() if window does not have
 *		front and back gadgets
 *  -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
 *
 *  -d#     Debug mode	(if compiled in)
 */

#include "dmouse.h"
#include <exec/libraries.h>

#define VERSION 25

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

long	ahtoi(char *);

extern	struct Library *SysBase;

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

    exists = (dms) ? 1 : 0;
    create = (dms) ? 0 : 1;

    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;
	dms->FBEnable = 1;
	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;

	/*
	 *  2.0 defaults
	 */

	if (SysBase->lib_Version >= 36)
	    dms->Workbench = 1;
    }

    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 'd':
	    dms->Debug = val;
	    break;
	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 'f':
	    dms->FBEnable = 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 'S':
	case 'M':
	    puts("-S and -M options obsolete");
	    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("DMouse (c)Copyright 1989-90, Matthew Dillon, All Rights Reserved\nV1.%02d, " __DATE__ "\n\n", VERSION);
	    puts("Freeware, redistributable for non-profit only");
	    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 = (long)LoadSeg("l:DMouse-Handler");
	if (!dms->Segment)
	    dms->Segment = (long)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 = (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.\n(c)Copyright 1989-90, Matthew Dillon, All Rights Reserved\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));
    }
    return(0);
}

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


