[comp.sources.amiga] v89i172: dmouse - mouse accelerator, screen blanker etc v1.20

page%swap@Sun.COM (Bob Page) (08/21/89)

Submitted-by: dillon@postgres.berkeley.edu (Matt Dillon)
Posting-number: Volume 89, Issue 172
Archive-name: intuition/dmouse120.1

DMouse V1.20 & DLineArt

The latest version of DMouse.  Also included is Steve -Raz- Berry's
DLineArt screen blanker program.  Simply run DLineArt after installing
DMouse and DMouse will use DLineArt for a screen blanker instead of its
own dull internal blanker.

DMouse no longer requires dres.library and will now compile under either
Manx C or Lattice C.  DLineArt currently compiles only under Manx C.

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	DMakefile.Aztec
#	DMakefile.Lattice
#	README
#	blanker.c
#	dlineart.c
#	dlineart.doc
#	dmouse-handler.c
#	dmouse-ipc.doc
#	dmouse.c
#	dmouse.doc
#	dmouse.h
# This is archive 1 of a 1-part kit.
# This archive created: Sun Aug 20 23:45:39 1989
echo "extracting DMakefile.Aztec"
sed 's/^X//' << \SHAR_EOF > DMakefile.Aztec
X
X#   DMakefile for DMouse, Aztec C V3.6a
X#
X#   +L = 32 bit ints
X
XSYMS=	aztec_include:symbols.m
XCFLAGS= +L +I$(SYMS)
XOD  = atmp:dmouse/
X
XDMOUSE	    = sys:altc/dmouse
XHANDLER     = l:dmouse-handler
XBLANKER     = srcc:blanker
XLINEART     = srcc:dlineart
X
Xall: $(DMOUSE) $(HANDLER) $(BLANKER) $(LINEART)
X
X$(DMOUSE) : $(OD)dmouse.o
X    ln +Q %(right) -lsup32 -lc32 -o %(left)
X
X$(HANDLER) : $(OD)dmouse-handler.o
X    ln +Q %(right) -lsup32 -lc32 -o %(left)
X
X$(BLANKER) : $(OD)blanker.o
X    ln +Q %(right) -lsup32 -lc32 -o %(left)
X
X$(LINEART) : $(OD)dlineart.o
X    ln +Q %(right) -lsup32 -lm32 -lc32 -o %(left)
X
X$(OD)dmouse.o $(OD)blanker.o : dmouse.c blanker.c
X    cc $(CFLAGS) %(right) -o %(left)
X
X$(OD)dmouse-handler.o : dmouse-handler.c
X    cc +B $(CFLAGS) %(right) -o %(left)
X
X
SHAR_EOF
echo "extracting DMakefile.Lattice"
sed 's/^X//' << \SHAR_EOF > DMakefile.Lattice
X
X#   DMakefile for DMouse,    Lattice C V5.03.99 and beyond
X
XSYMS=	lattice_include:symbols.m
X#CFLAGS= -iprivate_include: -cimq -O -v -rr -H$(SYMS)
XCFLAGS= -iprivate_include: -cimq -O -v -rr
X
XOD  = ltmp:dmouse/
X
XDMOUSE	    = dhb:altc/dmouse
XHANDLER     = l:dmouse-handler
XBLANKER     = srcc:blanker
XLINEART     = srcc:dlineart
XLIBS	    = lib:sup32.lib lib:lcr.lib lib:amiga.lib
X
X#SRCS	     = blanker.c dmouse.c dmouse-handler.c dlineart.c
XSRCS	    = dmouse.c dmouse-handler.c blanker.c
XOBJS	    = $(SRCS:"*.c":"$(OD)*.o")
X
X#all: $(DMOUSE) $(HANDLER) $(BLANKER) $(LINEART)
Xall: $(DMOUSE) $(HANDLER) $(BLANKER)
X
X$(DMOUSE) : $(OD)dmouse.o
X    blink FROM LIB:c.o %(right) LIB $(LIBS) TO %(left) BATCH
X
X$(HANDLER) : $(OD)dmouse-handler.o
X    blink FROM %(right) LIB $(LIBS) TO %(left) BATCH
X
X$(BLANKER) : $(OD)blanker.o
X     blink FROM LIB:c.o %(right) LIB $(LIBS) TO %(left) BATCH
X
X#$(LINEART) : $(OD)dlineart.o
X#    blink FROM LIB:c.o %(right) LIB $(LIBS) TO %(left) BATCH
X
X$(OBJS) : $(SRCS)
X    lc $(CFLAGS) -o%(left) %(right)
X
X
SHAR_EOF
echo "extracting README"
sed 's/^X//' << \SHAR_EOF > README
X
X		    README FILES FOR DMOUSE DISTRIBTION
X
X    Note, checkout the DMakefile's for required assignments before attempting
X    to make the source.  The 'dmake' program makes the source.
X
XDMakefile.Lattice	Lattice V5.02 DMakefile for dmake
XDMakefile.Aztec 	Aztec V3.6a   DMakefile for dmake
X
Xdmouse.doc		documentation
Xdmouse.c		source
Xdmouse.h		source
Xdmouse-handler.c	source
X
Xblanker.c		source to example blanker
Xdlineart.c		(currently compiles under Aztec C only)
X
Xlocal/*.h		general includes (from sup32.lib.  you need these to
X			compile DMouse as well as the link library binary)
X
Xdmake			required to compile the source
X
Xdmouse			dmouse executable.  control program
Xl:dmouse-handler	dmouse-handler should go into l:
X
X
X		    Quick Installation
X	       Please read the documentation!
X
X1> dmouse		    -install dmouse
X1> dmouse quit		    -quit out of dmouse
X1> dmouse help		    -show available options for dmouse
X
SHAR_EOF
echo "extracting blanker.c"
sed 's/^X//' << \SHAR_EOF > blanker.c
X
X/*
X *  BLANKER.C
X *
X *  Example external screen blanker for DMouse.
X */
X
X#include <local/typedefs.h>
X#include <local/ipc.h>
X#include <local/xmisc.h>
X
X#ifdef LATTICE
X#include <dos.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X
Xint __stdargs CXBRK(void);
X
X__stdargs	/*  bug in lcr.lib  */
XCXBRK()
X{
X    return(0);
X}
X
X#else
Xextern int Enable_Abort;    /*	CLI break enable	*/
X#endif
X
X
X#define RATE	1000000
X
Xtypedef struct IORequest IORequest;
X
Xstatic SCR *Scr;
Xstatic TA   Ta = {  (ubyte *)"topaz.font", 8 };
Xstatic NS   Ns = {  0, 0, 320, -1, 1, -1, -1, 0, CUSTOMSCREEN|SCREENQUIET, &Ta };
X
Xstatic IOT Iot;
Xstatic char Ioip;
Xstatic char *TStr = "Blank";
Xstatic char *TSpa = "     ";
Xstatic long TLen = 5;
X
Xvoid main ARGS((int, char **));
Xvoid screenon ARGS((void));
Xvoid screenoff ARGS((void));
Xvoid screengraphics ARGS((void));
Xlong myrand ARGS((void));
X
Xvoid
Xmain(ac,av)
Xchar **av;
X{
X    PORT *dmport;
X    PORT *ipport;
X    PORT *tp;
X    IORequest	AddReq;
X    IORequest	RemReq;
X    char foo;	/*  dummy   */
X    char notdone = 1;
X
X#ifndef LATTICE
X    Enable_Abort = 0;
X#endif
X
X    tp	   = CreatePort(NULL, 0);
X    ipport = CreatePort(NULL, 0);
X
X    AddReq.io_Message.mn_ReplyPort = ipport;
X    AddReq.io_Command = 0x84;
X    AddReq.io_Unit = (struct Unit *)&foo;
X    AddReq.io_Flags = 0x0C;	/* %1100 (screen blanker, no mouse blanker) */
X
X    RemReq.io_Message.mn_ReplyPort = ipport;
X    RemReq.io_Command = 0x85;
X    RemReq.io_Unit = (struct Unit *)&foo;
X
X    if (openlibs(INTUITION_LIB|GRAPHICS_LIB) == 0)
X	goto fail;
X    if (OpenDevice("timer.device", UNIT_VBLANK, &Iot, 0)) {
X	Write(Output(), "Unable to open timer.device\n", 28);
X	goto fail;
X    }
X    Iot.tr_node.io_Message.mn_ReplyPort = tp;
X    Iot.tr_node.io_Command = TR_ADDREQUEST;
X
X    SetSignal(0, SIGBREAKF_CTRL_C);
X    Forbid();
X    if (dmport = FindPort("DMouse.ipc"))
X	PutMsg(dmport, &AddReq.io_Message);
X    Permit();
X    if (dmport == NULL) {
X	puts("DMouse not running or <V1.20");
X	goto fail;
X    }
X
X    while (notdone) {
X	long mask = (1 << tp->mp_SigBit) | (1 << ipport->mp_SigBit) | SIGBREAKF_CTRL_C;
X	mask = Wait(mask);
X
X	if (mask & SIGBREAKF_CTRL_C) {
X	    notdone = 0;
X	}
X	if ((mask & (1 << tp->mp_SigBit)) && Scr && Ioip && CheckIO(&Iot)) {
X	    WaitIO(&Iot);
X	    Iot.tr_time.tv_secs  = RATE / 1000000;
X	    Iot.tr_time.tv_micro = RATE % 1000000;
X	    SendIO(&Iot);
X	    screengraphics();
X	}
X	if (mask & (1 << ipport->mp_SigBit)) {
X	    IORequest *ior;
X	    while (ior = (IORequest *)GetMsg(ipport)) {
X		if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG) {   /* my AddHand req */
X		    notdone = 0;
X		    continue;
X		}
X		switch(ior->io_Command) {
X		case 0x80:
X		case 0x81:
X		    break;
X		case 0x82:
X		    screenon();
X		    break;
X		case 0x83:
X		    screenoff();
X		    break;
X		case 0x86:
X		    notdone = 0;
X		    break;
X		}
X		ReplyMsg(&ior->io_Message);
X	    }
X	}
X    }
X    PutMsg(dmport, &RemReq.io_Message);
X    WaitMsg(&RemReq);
X    {
X	register IORequest *ior = NULL;
X	while (ior != &AddReq) {    /*  last msg will be AddReq */
X	    WaitPort(ipport);
X	    ior = (IORequest *)GetMsg(ipport);
X	    if (ior->io_Message.mn_Node.ln_Type == NT_MESSAGE)
X		ReplyMsg(&ior->io_Message);
X	}
X    }
Xfail:
X    if (Ioip) {
X	AbortIO(&Iot);
X	WaitIO(&Iot);
X    }
X    if (Iot.tr_node.io_Device)
X	CloseDevice(&Iot);
X    if (tp)
X	DeletePort(tp);
X    if (ipport)
X	DeletePort(ipport);
X    closelibs(-1);
X}
X
Xvoid
Xscreenoff()
X{
X    if (Scr)
X	ScreenToFront(Scr);
X    else if (Scr = OpenScreen(&Ns)) {
X	if (!Ioip) {
X	    Iot.tr_time.tv_secs  = 3;
X	    Iot.tr_time.tv_micro = 0;
X	    SendIO(&Iot);
X	    Ioip = 1;
X	}
X    }
X}
X
Xvoid
Xscreenon()
X{
X    if (Scr)
X	CloseScreen(Scr);
X    Scr = NULL;
X    if (Ioip) {
X	AbortIO(&Iot);
X	WaitIO(&Iot);
X	Ioip = 0;
X    }
X}
X
X/*
X *  Simple Stupid
X *
X *  Warning:  Note that no clipping is done when using the screen's
X *	      rastport, all rendering must be IN BOUNDS!
X */
X
Xvoid
Xscreengraphics()
X{
X    static short oldx, oldy;
X    short x, y;
X
X    x = (myrand() & 4095) % (Scr->Width - TextLength(&Scr->RastPort, TStr, TLen) - 8);
X    y = (myrand() & 4095) % (Scr->Height- Scr->RastPort.TxHeight - Scr->RastPort.TxBaseline - 8);
X    if (x < 0 || y < 0)
X	return;
X    y += Scr->RastPort.TxBaseline + 4;
X
X    SetAPen(&Scr->RastPort, 0);
X    Move(&Scr->RastPort, oldx, oldy);
X    Text(&Scr->RastPort, TSpa, TLen);
X
X    oldx = x;
X    oldy = y;
X    SetRGB4(&Scr->ViewPort, 1, myrand()&15, myrand()&15, myrand()&15);
X
X    SetAPen(&Scr->RastPort, 1);
X    Move(&Scr->RastPort, oldx, oldy);
X    Text(&Scr->RastPort, TStr, TLen);
X}
X
X
Xlong
Xmyrand()
X{
X    static long rv = 34987;
X    rv = (rv * 13 + 1) ^ (rv >> 13);
X    return(rv);
X}
X
X
X
SHAR_EOF
echo "extracting dlineart.c"
sed 's/^X//' << \SHAR_EOF > dlineart.c
X
X/*
X *  DLineArt.c
X *
X *  DMouse screen blanker for use with DMouse V1.20
X *
X *  read the docs file for installation procedures.
X *
X *  Is your computer BORED? If so, then you need...
X *
X *		DLineArt, by Steve -Raz- Berry with help
X *		from Matt Dillon.
X *
X *  Compile +L w/ sup32.lib.  libs:dres.library no longer required
X */
X
X#include <local/typedefs.h>
X#include <local/ipc.h>
X#include <local/xmisc.h>
X
Xtypedef struct IORequest IORequest;
X
X#define MAXELLIPSE 75
X
X/* Be carefule if modifiying the following defines... */
X
Xint MAXX, MAXY;
X
X#define MINBOUND 20
X#define BOUNDX MAXX-MINBOUND
X#define BOUNDY MAXY-MINBOUND
X
X#define TEXTSTR 0x10
X#define SPLINES 0x8
X#define LINES 0x4
X#define BOXES 0x2
X#define ELLIPSES 0x1
X
X/* Maximun # of lines,boxes,ellipses to draw (watch your stack!) */
X
X#define MAXLINES 500
X
XUWORD coltbl[2] = {
X    0x000,		/* background color */
X    0x500
X};
X
Xextern int Enable_Abort;
X
XRP *rp;
XVP *vp;
Xstatic SCR *Scr;
Xstatic WIN *Win;
Xstatic TA   Ta = {  (ubyte *)"topaz.font", 11 };
Xstatic NS   Ns = {  0, 0, 0, 0, 1, -1, -1, HIRES|LACE, CUSTOMSCREEN|SCREENQUIET, &Ta };
Xstatic NW   Nw = { 0, 0, 0, 0, 2, 1, NULL, BORDERLESS|NOCAREREFRESH|BACKDROP,
XNULL, NULL,NULL,NULL,NULL,0,0,8000,8000,CUSTOMSCREEN};
X
Xstatic long offset, scale1, scale2, flags;
Xstatic long count, trails, nice, all;
Xstatic long input, maxlines, ctemp;
Xstatic long point1[MAXLINES+1][2], point2[MAXLINES+1][2], direction[2][2];
X
Xstatic char *TStr = "BOING!";
Xstatic long TLen = 6;
X
Xvoid
XInitScrStructures()
X{
X    SCR scr;
X    if (GetScreenData(&scr, sizeof(scr), WBENCHSCREEN, NULL)) {
X	if (scr.ViewPort.Modes & HIRES)
X	    MAXX = scr.Width;
X	else
X	    MAXX = scr.Width * 2;
X	if (scr.ViewPort.Modes & LACE)
X	    MAXY = scr.Height;
X	else
X	    MAXY = scr.Height * 2;
X    } else {
X	MAXX = 640;
X	MAXY = 200;
X    }
X    Ns.Width  = MAXX;
X    Nw.Width  = MAXX;
X    Ns.Height = MAXY;
X    Nw.Height = MAXY;
X}
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X    int var;
X    IORequest AddReq;	/* for dmouse ipc	*/
X    IORequest RemReq;
X    PORT    *dmport;
X    PORT    *ipport;
X    char    foo;	/*  dummy variable, address used as id	*/
X    short   notdone = 1;
X
X    input  = 3; 	/* Some defaults for switches */
X    trails = 1;
X    maxlines = 20;
X    nice  = FALSE;
X    all   = FALSE;
X    flags = LINES;
X
X
X    Enable_Abort = 0;
X
X    while(--argc >= 1) {
X	switch (argv[argc][0]) {
X	    case '-':
X		switch (argv[argc][1]) {
X		    case 'T':
X			flags = TEXTSTR;
X			TStr = &argv[argc][2];
X			if (TStr[0] != \0)
X			    TLen = strlen(TStr);
X			break;
X		    case 's':
X			flags = SPLINES;
X			break;
X		    case 't':
X			trails = 0;
X			break;
X		    case 'n':
X			nice = TRUE;
X			break;
X		    case 'l':
X			maxlines = atoi(&argv[argc][2]);
X			maxlines = (maxlines > MAXLINES) ? MAXLINES : (maxlines < 1) ? 1 : maxlines;
X			break;
X		    case 'c':
X			ctemp = atoi(&argv[argc][2]);
X			coltbl[1] = (ctemp > 4096) ? 4096 : (ctemp < 1) ? 1 : ctemp;
X			break;
X		    case 'b':
X			flags = BOXES;
X			break;
X		    case 'e':
X			flags = ELLIPSES;
X			break;
X		    case 'a':
X			all = TRUE;
X			break;
X		    default:
X			exit(20);
X		}
X		break;
X	    default:
X		input = atoi(argv[argc]);
X		break;
X	}
X    }
X
X    input = (input > 9) ? 9 : (input < 0) ? 1 : input;
X
X    count = 0;
X    scale1 = 2;
X    scale2 = 2;
X    offset = 0;
X
X    ipport = CreatePort(NULL, 0);   /*  ipc port    */
X
X    if (openlibs(INTUITION_LIB|GRAPHICS_LIB) == 0)
X	goto fail;
X
X    InitScrStructures();
X
X    for(var = 0; var < VBeamPos(); ++var)
X	get_rand_point();
X
X    point1[0][0] = get_rand_point();    /* Initial start x,y (one endpoint) */
X    point1[0][1] = get_rand_point();
X
X    point2[0][0] = get_rand_point();
X    point2[0][1] = get_rand_point();
X
X    for(var = 0; var < 2; ++var){
X	direction[var][0] = get_rand_dir();
X	direction[var][1] = get_rand_dir();
X    }
X
X    AddReq.io_Message.mn_ReplyPort = ipport;
X    AddReq.io_Command = 0x84;
X    AddReq.io_Unit = (struct Unit *)&foo;
X    AddReq.io_Flags = 0x0C;	/* %1100 (screen blanker, no mouse blanker) */
X
X    RemReq.io_Message.mn_ReplyPort = ipport;
X    RemReq.io_Command = 0x85;
X    RemReq.io_Unit = (struct Unit *)&foo;
X
X    Forbid();
X    if (dmport = FindPort("DMouse.ipc"))
X	PutMsg(dmport, &AddReq.io_Message);
X    Permit();
X    if (dmport == NULL) {
X	puts("DMouse not running or <V1.20");
X	goto fail;
X    }
X
X    while (notdone) {
X	long mask = SIGBREAKF_CTRL_C | (1 << ipport->mp_SigBit);
X	if (Scr)
X	    mask = SetSignal(0L, mask);
X	else
X	    mask = Wait(mask);
X
X	if (mask & SIGBREAKF_CTRL_C)
X	    notdone = 0;
X	if (mask & (1 << ipport->mp_SigBit)) {
X	    IORequest *ior;
X	    while (ior = (IORequest *)GetMsg(ipport)) {
X		if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG) {
X		    notdone = 0;
X		    continue;
X		}
X		switch(ior->io_Command) {
X		case 0x82:
X		    screenon();
X		    break;
X		case 0x83:
X		    screenoff();
X		    break;
X		case 0x86:
X		    notdone = 0;
X		    break;
X		}
X		ReplyMsg(&ior->io_Message);
X	    }
X	}
X	if (Win)
X	    LineArt();
X    }
X    screenon();
X    PutMsg(dmport, &RemReq.io_Message);
X    {
X	register IORequest *ior = NULL;
X	while (ior != &AddReq) {
X	    WaitPort(ipport);
X	    ior = (IORequest *)GetMsg(ipport);
X	    if (ior->io_Message.mn_Node.ln_Type == NT_MESSAGE)
X		ReplyMsg(&ior->io_Message);
X	}
X    }
Xfail:
X    DeletePort(ipport);
X    closelibs(-1);
X}
X
Xscreenoff()
X{
X    if (Scr)
X	ScreenToFront(Scr);
X    else if (Scr = OpenScreen(&Ns)) {
X	Nw.Screen = Scr;
X	if (Win = OpenWindow(&Nw)){
X		vp = &Scr->ViewPort;
X		rp = Win->RPort;
X		LoadRGB4(vp,coltbl,2L);
X	}
X	ShowTitle(Scr, FALSE);
X    }
X}
X
Xscreenon()
X{
X    if (Win)
X	CloseWindow(Win);
X    if (Scr)
X	CloseScreen(Scr);
X    Win = NULL;
X    Scr = NULL;
X    vp = NULL;
X    rp = NULL;
X}
X
XLineArt()
X{
X    register int newoffset, tempx, tempy;
X
X    SetAPen(rp, 1L);
X
X    if (nice)
X	WaitTOF();
X
X    switch (flags) {
X    case LINES:
X	Move(rp, point1[offset][0], point1[offset][1]);
X	Draw(rp, point2[offset][0], point2[offset][1]);
X	break;
X    case ELLIPSES:
X	doellipse(offset);
X	break;
X    case BOXES:
X	dobox(offset);
X	break;
X    case SPLINES:
X	dospline(offset);
X	break;
X    case TEXTSTR:
X	doteresa(offset);
X	break;
X    }
X
X    if (checkbounce1(offset)) {
X	tempx = direction[0][0];
X	tempy = direction[0][1];
X
X	direction[0][0] = (point1[offset][0] <= MINBOUND) ? 1 :
X	(point1[offset][0] >= BOUNDX) ? -1 :
X	get_rand_dir();
X
X	direction[0][1] = (point1[offset][1] <= MINBOUND) ? 1 :
X	(point1[offset][1] >= BOUNDY) ? -1 :
X	get_rand_dir();
X
X	scale1 = get_rand_scale();
X    }
X
X    if (checkbounce2(offset)) {
X	tempx = direction[1][0];
X	tempy = direction[1][1];
X
X	direction[1][0] = (point2[offset][0] <= MINBOUND) ? 1 :
X	(point2[offset][0] >= BOUNDX) ? -1 :
X	get_rand_dir();
X
X	direction[1][1] = (point2[offset][1] <= MINBOUND) ? 1 :
X	(point2[offset][1] >= BOUNDY) ? -1 :
X	get_rand_dir();
X
X	scale2 = get_rand_scale();
X    }
X
X    if ((++count > 60000) | (count > 2500 && (flags == ELLIPSES))) {
X	count = maxlines;
X	if (trails == 0 | all) {
X	    count = 0;
X	    offset = 0;
X	    Move(rp, 0, 0);
X	    ClearScreen(rp);
X	}
X	if (all) {
X	    flags = flags << 1;
X	    if (flags > TEXTSTR)
X		flags = ELLIPSES;
X	}
X    }
X
X    if (++offset > maxlines){
X	coltbl[1]++;
X	LoadRGB4(vp,coltbl,2L);
X	if ((coltbl[1] && 0x00f) > 0xb) {
X	    coltbl[1] = coltbl[1] & 0xff0;
X	    coltbl[1] += 0x010;
X	}
X	if ((coltbl[1] && 0x0f0) > 0xb0) {
X	    coltbl[1] = coltbl[1] & 0xf0f;
X	    coltbl[1] += 0x100;
X	}
X	if ((coltbl[1] && 0xf00) > 0xb00) {
X	    coltbl[1] = ctemp;
X	}
X    }
X
X    if (offset > maxlines)
X	offset = 0;
X
X    /* Erase the oldest line... (or ellipse) */
X
X    if (count > maxlines-1) {
X	newoffset = (offset == maxlines) ? 0 : offset + trails;
X	SetAPen(rp, 0L);
X	switch (flags) {
X	case LINES:
X	    Move(rp, point1[newoffset][0], point1[newoffset][1]);
X	    Draw(rp, point2[newoffset][0], point2[newoffset][1]);
X	    break;
X	case ELLIPSES:
X	    doellipse(newoffset);
X	    break;
X	case BOXES:
X	    dobox(newoffset);
X	    break;
X	case SPLINES:
X	    dospline(newoffset);
X	    break;
X	case TEXTSTR:
X	    doteresa(newoffset);
X	    break;
X	}
X	SetAPen(rp, 1L);
X    }
X
X    /* Calculate the next point */
X
X    newoffset = (offset > 0) ? offset-1 : maxlines;
X    point1[offset][0] = (scale1 * direction[0][0]) + point1[newoffset][0];
X    point1[offset][1] = (scale1 * direction[0][1]) + point1[newoffset][1];
X
X    if (flags != TEXTSTR){
X      point2[offset][0] = (scale2 * direction[1][0]) + point2[newoffset][0];
X      point2[offset][1] = (scale2 * direction[1][1]) + point2[newoffset][1];
X    } else {
X      point2[offset][0] = point1[offset][0] + TextLength(rp, TStr, TLen);
X      point2[offset][1] = point1[offset][1];
X    }
X}
X
Xdoteresa(offset)
Xint offset;
X{
X    register short x,y;
X
X    x = (Scr->Width - TextLength(rp, TStr, TLen) - 20);
X    y = (Scr->Height- Scr->RastPort.TxHeight - Scr->RastPort.TxBaseline - 8);
X
X    if (x < 0 || y < 0)
X	return;
X
X    x = (x < point1[offset][0]) ? x : point1[offset][0];
X    y = (y < point1[offset][1]) ? y : point1[offset][1];
X
X    Move(rp, x, y);
X    Text(rp, TStr, TLen);
X}
X
Xdoellipse(newoffset)
Xregister int newoffset;
X{
X    register int tempx,tempy;
X
X    tempx = (point2[newoffset][0] > point1[newoffset][0]) ?
X	point2[newoffset][0] - point1[newoffset][0] :
X	point1[newoffset][0] - point2[newoffset][0];
X
X    tempy = (point2[newoffset][1] > point1[newoffset][1]) ?
X	point2[newoffset][1] - point1[newoffset][1] :
X	point1[newoffset][1] - point2[newoffset][1];
X
X    tempx = (tempx > point1[newoffset][0]) ? point1[newoffset][0] :
X	((tempx + point1[newoffset][0]) > BOUNDX) ? BOUNDX - point1[newoffset][0] :
X	tempx;
X
X    tempy = (tempy > point1[newoffset][1]) ? point1[newoffset][1] :
X	((tempy + point1[newoffset][1]) > BOUNDY) ? BOUNDY - point1[newoffset][1] :
X	tempy;
X
X    tempx = (tempx > MAXELLIPSE) ? MAXELLIPSE : tempx;
X    tempy = (tempy > MAXELLIPSE) ? MAXELLIPSE : tempy;
X
X    if (tempx > 0 && tempy > 0)
X	DrawEllipse(rp, point1[newoffset][0], point1[newoffset][1], tempx, tempy);
X}
X
Xdobox(offset)
Xregister int offset;
X{
X    register int tempx, tempy;
X
X    Move(rp, point1[offset][0], point1[offset][1]);
X    Draw(rp, point2[offset][0], point2[offset][1]);
X
X    tempx = MAXX - point1[offset][0];
X    tempy = MAXY - point1[offset][1];
X
X    if (tempx >= 0 && tempy >= 0)
X	Draw(rp, tempx, tempy);
X
X    tempx = MAXX - point2[offset][0];
X    tempy = MAXY - point2[offset][1];
X
X    if (tempx >= 0 || tempy >= 0)
X	Draw(rp, tempx, tempy);
X
X    Draw(rp, point1[offset][0], point1[offset][1]);
X}
X
Xlong checkbounce1(index)
Xregister int index;
X{
X
X    return (point1[index][0] >= BOUNDX) | (point1[index][1] >= BOUNDY) |
X	    (point1[index][0] <= MINBOUND) | (point1[index][1] <= MINBOUND);
X}
X
Xlong checkbounce2(index)
Xregister int index;
X{
X    return (point2[index][0] >= BOUNDX) | (point2[index][1] >= BOUNDY) |
X	    (point2[index][0] <= MINBOUND) | (point2[index][1] <= MINBOUND);
X}
X
Xint get_rand_point()
X{
X    register short temp;
X
X    temp = ran();
X    if (temp < 0)
X	temp = temp * -1;
X    temp = temp/319+19;
X
X    return (temp > MAXY) ? MAXY : temp ;
X}
X
Xint get_rand_dir()
X{
X    register short num;
X
X    num = ran((short)3);
X
X    return (num < -5000) ? -1 : (num > 5000) ? 1 : 0;
X}
X
Xint get_rand_scale()
X{
X    register short temp;
X
X    temp = ran();
X    if (temp < 0)
X	temp = temp * -1;
X    temp = temp/6560 + (short)input;
X
X    return (temp > 17) ? 17 : temp;
X}
X
X#define MAXPOINTS 5
X#define FIX(x) (((long)(x)) << 7)
X
X/*
X *   Draws a spline!  Expects all arguments in registers.
X */
X#asm
X	public	_Draw
X	cseg
Xrspline
X	move.l	a0,d0
X	sub.l	d6,d0
X	move.l	d0,d3
X	bpl	save1
X	neg.l	d0
Xsave1
X	move.l	a1,d1
X	sub.l	d7,d1
X	move.l	d1,d4
X	bpl	save2
X	neg.l	d1
Xsave2
X	move.l	d0,d2
X	cmp.l	d0,d1
X	bmi	save3
X	lsr.l	#3,d2
X	bra	save9
Xsave3
X	lsr.l	#3,d1
Xsave9
X	add.l	d1,d2
X	asr.l	#3,d2
X	asr.l	#5,d3
X	asr.l	#5,d4
X	move.l	a2,d0
X	sub.l	a0,d0
X	move.l	a3,d1
X	sub.l	a1,d1
X	asr.l	#5,d0
X	asr.l	#5,d1
X	muls.w	d4,d0
X	muls.w	d3,d1
X	sub.l	d1,d0
X	bpl	save4
X	neg.l	d0
Xsave4
X	cmp.l	d0,d2
X	bmi	pushem
X	move.l	a5,d0
X	sub.l	a0,d0
X	move.l	a6,d1
X	sub.l	a1,d1
X	asr.l	#5,d0
X	asr.l	#5,d1
X	muls.w	d4,d0
X	muls.w	d3,d1
X	sub.l	d1,d0
X	bpl	save5
X	neg.l	d0
Xsave5
X	cmp.l	d0,d2
X	bmi	pushem
Xmakeline
X	lsr.l	#7,d7
X	move.l	d7,-(sp)
X	lsr.l	#7,d6
X	move.l	d6,-(sp)
X	move.l	_rp,-(sp)
X	jsr	_Draw
X	add.w	#12,a7
X	rts
Xpushem
X	movem.l d6/d7,-(sp)
X	move.l	a5,d0
X	add.l	d6,d0
X	asr.l	#1,d0
X	move.l	a6,d1
X	add.l	d7,d1
X	asr.l	#1,d1
X	movem.l d0/d1,-(sp)
X	move.l	a2,d2
X	add.l	a5,d2
X	asr.l	#1,d2
X	move.l	a3,d3
X	add.l	a6,d3
X	asr.l	#1,d3
X	move.l	d0,d4
X	add.l	d2,d4
X	asr.l	#1,d4
X	move.l	d1,d5
X	add.l	d3,d5
X	asr.l	#1,d5
X	movem.l d4/d5,-(sp)
X	move.l	a0,d6
X	add.l	a2,d6
X	asr.l	#1,d6
X	move.l	a1,d7
X	add.l	a3,d7
X	asr.l	#1,d7
X	move.l	d2,d0
X	add.l	d6,d0
X	asr.l	#1,d0
X	move.l	d3,d1
X	add.l	d7,d1
X	asr.l	#1,d1
X	move.l	d6,a2
X	move.l	d7,a3
X	move.l	d0,d6
X	add.l	d4,d6
X	asr.l	#1,d6
X	move.l	d1,d7
X	add.l	d5,d7
X	asr.l	#1,d7
X	movem.l d6/d7,-(sp)
X	move.l	d0,a5
X	move.l	d1,a6
X	jsr	rspline
X	movem.l (sp)+,a0/a1
X	movem.l (sp)+,a2/a3/a5/a6
X	movem.l (sp)+,d6/d7
X	bra	rspline
X#endasm
X/*
X *   Now our linkage to the spline routine.  Parameters are in 8(a5)...
X */
Xint drawspline(x1, y1, x2, y2, x3, y3, x4, y4)
Xlong x1, y1, x2, y2, x3, y3, x4, y4 ;
X{
X#asm
X	movem.l saver,-(sp)
X	move.l	8(a5),a0
X	move.l	12(a5),a1
X	move.l	16(a5),a2
X	move.l	20(a5),a3
X	move.l	28(a5),a6
X	move.l	32(a5),d6
X	move.l	36(a5),d7
X	move.l	24(a5),a5
X	jsr	rspline
X	movem.l (sp)+,saver
Xsaver	reg	d0-d7/a0-a6
X#endasm
X}
X
X/*
X *   Here we draw splines!  Magic, you know.
X */
Xdospline(index)
Xregister int index;
X{
X    int index1;
X
X    if (index == 0)
X	index1 = maxlines;
X    else
X	index1 = index - 1;
X
X    Move(rp, (long)(point1[index][0]), (long)(point1[index][1])) ;
X    drawspline(FIX(point1[index][0]), FIX(point1[index][1]),
X	      FIX(point2[index][1]), FIX(point2[index][1]),
X	      FIX(point1[index1][0]), FIX(point1[index1][1]),
X	      FIX(point2[index1][0]), FIX(point2[index1][1])) ;
X}
X
X
SHAR_EOF
echo "extracting dlineart.doc"
sed 's/^X//' << \SHAR_EOF > dlineart.doc
X
X    Is your computer BORED? If so, then you need...
X
X		DLineArt, by Steve -Raz- Berry with help
X		from Matt Dillon.
X
X    IF YOU ARE IMPATIENT WITH LONG WINDED README'S... skip to the section
Xlabeled Examples and try them out...
X
X This program must be used in conjunction with Dmouse 1.13, and is
X intended to be a screen blanker replacement program. IT IS NOT
X STAND ALONE. An earlier release of LineArt works without Dmouse.
X
X0) SHORT HISTORY
X----------------
X
X    This display hack does nothing usefull, but draw pretty lines on a
Xcustom screen. I have seen this program running on everything from Suns
Xto Mac's, and I decided that it was time that one was done for the Amiga.
XAlthough similar to the lines demo distributed on Workbench 1.1 & 1.2,
XIt does things on it's own screen in full 4096 color interlaced
Xsplendor :*).
X
X    Matt Dillon liked it so much that he stitched in a way to
Xadd your own customized screen blanker via an IPC port. As soon as
XI found Dmouse 1.13, I took his example "blanker.c", and hacked it
Xup to support LineArt graphics. I also fixed a few bugs and added a few
Xmore things along the way.
X
X    When I first wrote this program, I was unaware of MACKIE written by
XTom Rokicki, which draws the same kind of lines boxes and splines
Xas part of a hot-key/screen-blanker type program. Undaunted (although
Xsomewhat embarassed) I proceeded to allow infinite customization
Xto those who are bored enough to want to play with LineArt. Besides, I prefer
XDMOUSE (Thanks Matt!) for my hot-key handler. Don't get me wrong, I really
Xlike the way Tom does splines... In fact I stole his spline code and put
Xit in (D)LineArt.
X
X1) TO GET DMOUSE TO RECOGNIZE DLineArt -
X--------------------------------------
X
X    To make dmouse (v1.20+) use the DLineArt screen blanker instead of its
X    default blanker (a boring blank screen) simply run DLineArt after you
X    initialize dmouse.
X
X------------------------------------------------------
Xstack 4000
Xdmouse -a4 -m3 -s90 -l0003 -w1 -t7 -C NewWSH
Xrunback -1 DLineArt -a -n 3 -c2500 -l30
X
X------------------------------------------------------
X
X    To terminate DLineArt do this:
X
Xraz's prompt> status
XProcess  1: Loaded as command: dlineart
XProcess  3: Loaded as command: status
Xraz's prompt> break 1
X
X The break command will terminate DLineArt.
X
X Terminating DMouse (1> dmouse quit) will also terminate DLineArt.
X
X2) INVOCATION:
X-------------
X
XThere are a LOT of comand line options (for a program like this anyway)!
X
X You need to run DLineArt in the background for it to function properly.
X You can enter the options in ANY order on the command line, and only the
X last occurance of a particular switch will be used. The options are:
X
X    run >nil: <nil: DLineArt -[b|t|n|e|c{0-4096}|l{2-1000}] [i]
X
X or use the PD 'runback' program to start DLineArt.
X
X The '-l' and '-c' options require an integer immediately following the
X switch in the range indicated in the {}'s, without a space. Descriptions
X and examples follow.
X
X   Dlineart -t	    - This leaves a trail (one out of every 'l' lines)
X		      remains on the screen.
X
X	    -s	    - Draw splines. Code blatently ripped off from Tomas
X		      Rokicki's Mackie.
X
X	    "-Tstring"
X		    - This option allows you to "bounce" words around the
X		      screen. You MUST enclose quotes around the entire
X		      string. This example will use "string". The default
X		      is the string "BOING!"
X
X	    -n	    - This is the 'nice' option, this makes LineArt much
X		      more friendly in a multitasking environment
X		      (It takes less CPU time.) It also slows things down.
X
X	    -cXXXX  - This switch allows you to specify the initial color
X		      that the program will cycle from. Suggested color
X		      values start from 1900 (decimal) and up.
X
X	    -lXXXX  - This switch allows you to specify the number of
X		      lines to be drawn before the last one is erased.
X
X	    -b	    - draw boxes (4 connected lines) instead of lines.
X
X	    i	    - This is an integer between 1 and 9 that will change
X		      the minimum distance between sucessive endpoints for
X		      each line drawn. A high number will give the illusion
X		      of unbelievable speed! (Woah... hold me down Toto!)
X
X	    -e	    - Draw ellipses instead of anything else.
X		      (I would be interested to see this run with an '020)
X
X	    -a	    - Cycle through all of the available line (and circle)
X		      types. This is a good loop mode.
X
XThe defaults (if you just type 'run lineart') are as if you entered:
X
X run <nil: >nil: DLineArt 3 -a -c1280 -l10 -TBOING!
X
X3) EXAMPLES:
X-----------
X
X Some of my favorites:
X
X    runback DLineArt 4 -l100 -c2500 -n
X    runback DLineArt 1 -l10 -c2500
X    runback DLineArt 9 -l30 -c2500 -n
X    runback DLineArt 9 -l30 -c2500 -t
X    runback DLineArt 4 -l3 -c1500 -n
X    runback DLineArt -b -c2500 1 -l20
X    runback DLineArt -s -c2500 4 -l35
X    runback DLineArt "-TI love Teresa!" -c2500 9 -n -l20
X    runback DLineArt -e 7 -c1999 -l30
X
X For speed freaks -
X    run <nil: >nil: DLineArt 9 -c4000 -l7
X
X4) Miscelaneous:
X---------------
X
X    If you want to time the drawing speed (roughly) turn on the trailing option
X    and wait for the screen to clear. 60,000 lines would have been drawn in
X    this amount of time.
X
X    I timed it at 2'7" (127 seconds) or 944 lines per second in line draw
X    mode. Using boxes it climbs to 2400 vectors per second. Not too shabby for
X    a game machine eh?
X
X5) Future improvements:
X
X    It could be faster, if I use the screen's rastport instead of the
X    windows'. Unfortuneately, CED (which is an excellent editor) does not
X    co-exist with DLineart when doing this. I have no clue why this is so.
X    The only symptoms are that retrieving CED via hot-key produces an instant
X    GURU. And no, I am NOT drawing out of bounds of the rastport, you
X    should have seen the debugging code I put in to make sure of that!
X
X------------------------------------------------------------------------
X
X   This program is PD. Use it or abuse it, only you will know.
X
X    Steve -Raz- Berry	    (Note the new address)
X    1260 Ayala Dr. #214
X    Sunnyvale, Ca. 94086
X
X    UUCP: ...sun!kilowatt!raz	ARPA: raz%kilowatt.EBay@sun.com
X
X	If you are on USENET, please feel free to use the archive server
X	on kilowatt. Just send a message of "send help" to the
X
X		archive-server%kilowatt.EBay@Sun.com
X	or	{well bonded site}!sun!kilowatt!archive-server
X
X	The archive has *all* of the binaries and sources that Bob Page
X	has posted and some from the days of Pat White. Currently this
X	totals to over 40 meg of stuff (zoo'ed and uuencoded).
X
X   This program is a Public Domain product of The Checkered Ball 1989.
X
X    8/07/89
SHAR_EOF
echo "extracting dmouse-handler.c"
sed 's/^X//' << \SHAR_EOF > dmouse-handler.c
X
X/*
X *  DMOUSE-HANDLER.C
X *
X *  (c)Copyright 1989 by Matthew Dillon, All Rights Reserved
X *
X *  V1.20, last revision 3 August 1989
X *
X *  Note on upping the handler process priority.  This is done to cause the
X *  handler task to get CPU before the current input event completes its
X *  processing so intuition calls made by the process are executed before
X *  the event is propogated.  If said intuition calls block, it's ok
X *  because they are not blocking the input handler process.
X */
X
X#include "dmouse.h"
X
X#ifdef LATTICE
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#endif
X
X/*typedef struct Layer	      LAYER;*/
Xtypedef struct IE	    *IEP;
Xtypedef struct IORequest    IORequest;
X
XDMS	*Dms		       = NULL;
XIBASE	*IntuitionBase	       = NULL;
XGFXBASE *GfxBase	       = NULL;
Xstruct LayersBase  *LayersBase = NULL;
Xstruct ExecBase    *SysBase    = NULL;
X
Xstatic PORT	*IOPort = NULL;     /*	For IPC messages		  */
Xstatic LIST	BlankList;	    /*	list of external blanker programs */
X
Xstatic char	STimedout = 0;
Xstatic char	MTimedout = 0;
Xstatic long	STime = 0, MTime = 0;
X#ifdef DEBUG
Xstatic long	DBFh = NULL;
X#endif
X
X
X#define IBASE IntuitionBase
X
XNS	Ns = {	0, 0, 64, -1, 1, -1, -1, 0, CUSTOMSCREEN|SCREENQUIET };
XIE DummyIE = { 0 };
X
Xshort	NRMe;	/*  Don't Repeat Mouse Events   */
X
X#ifdef LATTICE
X__asm __saveds IEP handler(register __a0 IE *event);
X#else
XIE *handler();
X#endif
X
XLAYER *WhichMouseLayer ARGS((void));
Xvoid sendrequest ARGS((long, IE *));
XLAYER *WhichMouseLayer ARGS((void));
Xint doipcmsg ARGS((short));
Xvoid DeleteBlanker ARGS((IORequest *));
X__saveds void noname ARGS((void));
X
X#ifdef LATTICE
X__saveds void
Xnoname()
X#else
X_main()
X#endif
X{
X
X    reg DMS *dms;
X    IOR  *ior;
X    INT addhand;
X
X#ifndef LATTICE
X    geta4();
X#endif
X    SysBase = *(struct ExecBase **)4;
X#ifdef LATTICE
X    {
X	DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
X    }
X#endif
X    {
X	reg PROC *proc = (PROC *)FindTask(NULL);
X	proc->pr_ConsoleTask = NULL;
X    }
X    NRMe = 0;
X    dms = Dms = (DMS *)FindPort(PORTNAME);
X    if (!dms)
X	return;
X    dms->Port.mp_Flags = PA_SIGNAL;
X    dms->Port.mp_SigBit = AllocSignal(-1);
X    dms->Port.mp_SigTask = FindTask(NULL);
X    dms->HandTask = dms->Port.mp_SigTask;
X    ior = CreateStdIO(&dms->Port);
X    IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
X    GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
X    LayersBase = (struct LayersBase *)OpenLibrary("layers.library", 0);
X    IOPort = CreatePort("DMouse.ipc", 0);
X    NewList(&BlankList);
X
X    if (!IntuitionBase || !GfxBase || !LayersBase)
X	goto startupfail;
X    addhand.is_Node.ln_Pri = dms->IPri;
X    addhand.is_Code = (FPTR)handler;
X    addhand.is_Data = NULL;
X
X    if (OpenDevice("input.device", 0, ior, 0)) {
X	goto startupfail;
X    } else {
X	SCR *scr = NULL;
X	uword *SprSavePtr = NULL;
X	long ipc_mask;
X
X	Signal(dms->ShakeTask, 1 << dms->ShakeSig);
X	ior->io_Command = IND_ADDHANDLER;
X	ior->io_Data = (APTR)&addhand;
X	ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
X	DoIO(ior);
X
X	ipc_mask = 1 << IOPort->mp_SigBit;
X
X	for (;;) {
X	    reg long sigs = Wait(SBF_C|(1<<dms->Port.mp_SigBit)|ipc_mask);
X	    if (sigs & (1 << dms->Port.mp_SigBit)) {
X		reg REQ *msg;
X		while (msg = (REQ *)GetMsg(&dms->Port)) {
X		    switch((long)msg->Msg.mn_Node.ln_Name) {
X		    case REQ_SCREENON:
X			if (scr)
X			    CloseScreen(scr);
X			scr = NULL;
X			doipcmsg(0x82);
X			break;
X		    case REQ_SCREENOFF:
X			if (scr)
X			    ScreenToFront(scr);
X			if (doipcmsg(0x83) == 0 && scr == NULL) {
X			    if (scr = OpenScreen(&Ns))
X				SetRGB4(&scr->ViewPort, 0, 0, 0, 0);
X			}
X			break;
X		    case REQ_MOUSEON:
X			if (SprSavePtr) {
X			    register COPINIT *ci = GfxBase->copinit;
X			    ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
X			    ci->sprstrtup[3] = (uword)(long)SprSavePtr;
X			    SprSavePtr = NULL;
X			}
X			doipcmsg(0x80);
X			break;
X		    case REQ_MOUSEOFF:
X			if (doipcmsg(0x81) == 0) {
X			    reg COPINIT *ci = GfxBase->copinit;
X			    if (ci->sprstrtup[0] != 0x120 || ci->sprstrtup[2] != 0x122)
X				break;
X
X			    if (!SprSavePtr)
X				SprSavePtr = (uword *)((ci->sprstrtup[1] << 16) | ci->sprstrtup[3]);
X			    ci->sprstrtup[1] = (ulong)dms->NoSprData >> 16;
X			    ci->sprstrtup[3] = (uword)(long)dms->NoSprData;
X			}
X			break;
X		    case REQ_DOCMD:
X			{
X			    long fh = (long)Open("nil:", 1006);
X			    Execute(dms->Cmd, NULL, fh);
X			    if (fh)
X				Close(fh);
X			}
X			break;
X		    case REQ_RAWMOUSE:
X			{
X			    register LAYER *layer;
X
X			    NRMe = 0;
X			    Forbid();
X			    layer = WhichMouseLayer();
X			    if (msg->ie_Code == IECODE_RBUTTON && dms->LMBEnable && (msg->ie_Qualifier & dms->RQual)) {
X				register WIN *win;
X				if (layer && (win = (WIN *)layer->Window) && !(win->Flags & BACKDROP) && (win->NextWindow || win->WScreen->FirstWindow != win)) {
X				    if (dms->Workbench)
X					WindowToBack(win);
X				    else
X					BehindLayer(0, layer);
X				} else if (IBASE->FirstScreen)
X				    ScreenToBack(IBASE->FirstScreen);
X			    }
X			    if (layer && layer->Window) {
X				if (msg->ie_Code == IECODE_LBUTTON && !(((WIN *)layer->Window)->Flags & BACKDROP) && dms->LMBEnable && layer->ClipRect && layer->ClipRect->Next) {
X				    /*
X				     *	Note: Case where it is the 'first' click in a series, where dms->CTime is
X				     *	      garbage, works properly no matter what DoubleClick returns.
X				     */
X				    if (dms->LQual == 0 || (msg->ie_Qualifier & dms->LQual)) {
X					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))
X					    --dms->CLeft;
X					else
X					    dms->CLeft = dms->Clicks - 1;
X					dms->CTime = msg->ie_TimeStamp;
X					dms->CWin = (WIN *)layer->Window;
X					if (dms->CLeft == 0) {
X					    dms->CLeft = dms->Clicks;
X					    if (dms->Workbench)
X						WindowToFront((WIN *)layer->Window);
X					    else
X						UpfrontLayer(0, layer);
X					}
X				    }
X				}
X				if ((dms->AAEnable & 1) && (void *)layer->Window != (void *)IBASE->ActiveWindow && msg->ie_Code == IECODE_NOBUTTON && !(msg->ie_Qualifier & 0x7000)) {
X				    if (!IBASE->ActiveWindow || !IBASE->ActiveWindow->FirstRequest)
X					ActivateWindow((WIN *)layer->Window);
X				}
X			    }
X			    Permit();
X			}
X			break;
X		    case REQ_RAWKEY:
X			{
X			    register LAYER *layer;
X
X			    Forbid();
X			    layer = WhichMouseLayer();
X			    if (layer && layer->Window && (void *)layer->Window != (void *)IBASE->ActiveWindow) {
X				if (!IBASE->ActiveWindow || !IBASE->ActiveWindow->FirstRequest)
X				    ActivateWindow((WIN *)layer->Window);
X			    }
X			    Permit();
X			}
X			break;
X#ifdef DEBUG
X		    case REQ_DEBUG:
X			{
X			    char buf[128];
X			    if (!DBFh) {
X				DBFh = Open("con:0/0/400/100/dmouse-debug", 1006);
X				if (!DBFh)
X				    break;
X			    }
X			    sprintf(buf, "%02lx %04lx %04lx\n",
X				msg->ie_Class,
X				msg->ie_Code,
X				msg->ie_Qualifier
X			    );
X			    Write(DBFh, buf, strlen(buf));
X			}
X			break;
X		    case REQ_DEBUGOFF:
X			if (DBFh) {
X			    Close(DBFh);
X			    DBFh = NULL;
X			}
X			break;
X#endif
X		    }
X		    FreeMem(msg, msg->Msg.mn_Length);
X		}
X	    }
X	    if (sigs & SBF_C)
X		break;
X
X	    /*
X	     *	IPC request.
X	     */
X
X	    if (sigs & ipc_mask) {
X		reg IORequest *ior;
X		while (ior = (IORequest *)GetMsg(IOPort)) {
X		    long req = 0;
X
X		    if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG) {
X			FreeMem(ior, ior->io_Message.mn_Length);
X			continue;
X		    }
X
X		    ior->io_Error = 0;
X		    switch(ior->io_Command) {
X		    case 0x80:	/* mouse on  */
X			req = REQ_MOUSEON;
X			break;
X		    case 0x81:	/* mouse off */
X			req = REQ_MOUSEOFF;
X			MTimedout = 1;
X			break;
X		    case 0x82:	/* screen on */
X			req = REQ_SCREENON;
X			break;
X		    case 0x83:	/* screen off*/
X			req = REQ_SCREENOFF;
X			STimedout = 1;
X			break;
X		    case 0x84:	/* add hand  */
X			AddHead(&BlankList, ior);
X			ior = NULL;
X			break;
X		    case 0x85:	/* rem hand  */
X			DeleteBlanker(ior);
X			ior = NULL;
X			break;
X		    }
X		    if (req)
X			sendrequest(req, NULL);
X		    if (ior)
X			ReplyMsg(&ior->io_Message);
X		}
X	    }
X	}
X#ifdef DEBUG
X	if (DBFh) {
X	    Close(DBFh);
X	    DBFh = NULL;
X	}
X#endif
X	ior->io_Command = IND_REMHANDLER;
X	ior->io_Data = (APTR)&addhand;
X	ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
X	DoIO(ior);
X	ior->io_Command = IND_WRITEEVENT;	/*  NULL EVENT	*/
X	ior->io_Length = sizeof(IE);
X	ior->io_Data = (APTR)&DummyIE;
X	ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
X	DoIO(ior);
X	CloseDevice(ior);
X	{
X	    reg MSG *msg;
X	    while (msg = GetMsg(&dms->Port))
X		FreeMem(msg, msg->mn_Length);
X	}
X	if (scr)
X	    CloseScreen(scr);
X	if (SprSavePtr) {
X	    reg COPINIT *ci = GfxBase->copinit;
X	    ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
X	    ci->sprstrtup[3] = (uword)(long)SprSavePtr;
X	    SprSavePtr = NULL;
X	}
X    }
X    goto closedown;
Xstartupfail:
X    dms->StartupError = 1;
X    Signal(dms->ShakeTask, 1 << dms->ShakeSig);
X    Wait(SBF_C);
Xclosedown:
X    DeleteStdIO(ior);
Xfail:
X    if (IOPort) {
X	IORequest *ior;     /*	wait for RemReq messages */
X
X	doipcmsg(0x86);     /*  send closedown requests  */
X	Forbid();
X	while (GetHead(&BlankList)) {
X	    WaitPort(IOPort);
X	    while (ior = (IORequest *)GetMsg(IOPort)) {
X		if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG) {
X		    FreeMem(ior, ior->io_Message.mn_Length);
X		    continue;
X		}
X		if (ior->io_Command == 0x85)    /*  receive remove req  */
X		    DeleteBlanker(ior);
X		else
X		    ReplyMsg(&ior->io_Message);              /*  ignore other reqs   */
X	    }
X	}
X	DeletePort(IOPort);
X	Permit();
X    }
X    if (IntuitionBase)
X	CloseLibrary((LIB *)IntuitionBase);
X    if (GfxBase)
X	CloseLibrary((LIB *)GfxBase);
X    if (LayersBase)
X	CloseLibrary((LIB *)LayersBase);
X#ifdef LATTICE
X    {
X	CloseLibrary((LIB *)DOSBase);
X    }
X#endif
X    Forbid();
X    Signal(dms->ShakeTask, 1 << dms->ShakeSig);
X}
X
Xvoid
XDeleteBlanker(ior)
XIORequest *ior;
X{
X    IORequest *io2;
X
X    ior->io_Error = 0;
X    for (io2 = GetHead(&BlankList); io2; io2 = GetSucc(io2)) {
X	if (io2->io_Unit == ior->io_Unit) {
X	    Remove(io2);
X	    if (ior)
X		ReplyMsg(&ior->io_Message);
X	    ReplyMsg(&io2->io_Message);
X	    ior = NULL;
X	}
X    }
X    if (ior) {
X	ior->io_Error = -1;
X	ReplyMsg(&ior->io_Message);
X    }
X}
X
Xdoipcmsg(cmd)
Xshort cmd;
X{
X    short count = 0;
X    short flags = 1 << (cmd & 0x7F);    /*  enable flags */
X    IORequest *iob, *io;
X
X    for (iob = GetHead(&BlankList); iob; iob = GetSucc(iob)) {
X	if (cmd == 0x86 || (iob->io_Flags & flags)) {
X	    io = AllocMem(sizeof(IORequest), MEMF_PUBLIC|MEMF_CLEAR);
X	    if (io) {
X		io->io_Command = cmd;
X		io->io_Unit = iob->io_Unit;
X		io->io_Message.mn_ReplyPort = IOPort;
X		io->io_Message.mn_Length = sizeof(IORequest);
X		PutMsg(iob->io_Message.mn_ReplyPort, &io->io_Message);
X		++count;
X	    }
X	}
X    }
X    return((int)count);
X}
X
X/*
X *  The INPUT.DEVICE HANDLER
X *
X *  Note that for Lattice V5.02 and beyond we need no
X *  assembly tags because we can specify that the arguments
X *  are passed in registers.
X */
X
X#ifndef LATTICE
X
X#asm
X	    ;	A0 = pointer to event linked list
X	    ;	A1 = pointer to my data segment
X	    ;	return new event linked list in D0
X
X	    public  _CHandler
X
X_handler:
X	    movem.l D2/D3/A0/A1/A4/A6,-(sp)
X	    jsr     _CHandler
X	    movem.l (sp)+,D2/D3/A0/A1/A4/A6
X	    rts
X
X#endasm
X
X#endif
X
X/*
X *  (1) Accellerate mouse movements.
X *  (2) Auto-Select window
X */
X
X#ifdef LATTICE
X
X__asm __saveds IEP
Xhandler(register __a0 IE *Ev)
X{
X
X#else
X
XIE *
XCHandler(scr0, scr1, Ev)
Xlong scr0;
Xlong scr1;
XIE *Ev;
X{
X#endif
X    reg IE *ev;
X    reg DMS *dms;
X
X#ifndef LATTICE
X    geta4();
X#endif
X    dms = Dms;
X    for (ev = Ev; ev; ev = Ev->ie_NextEvent) {
X#ifdef DEBUG
X	if (dms->Debug) {
X	    if (ev->ie_Class != IECLASS_TIMER)
X		sendrequest(REQ_DEBUG, ev);
X	} else if (DBFh) {
X	    sendrequest(REQ_DEBUGOFF, ev);
X	}
X#endif
X	switch(ev->ie_Class) {
X	case IECLASS_RAWMOUSE:
X	    /*
X	     *	Mouse events restore both the screen and mouse pointer.
X	     */
X
X	    STime = ev->ie_TimeStamp.tv_secs + dms->STo;
X	    MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
X	    if (STimedout)
X		sendrequest(REQ_SCREENON, ev);
X	    if (MTimedout)
X		sendrequest(REQ_MOUSEON, ev);
X	    STimedout = MTimedout = 0;
X
X	    /*
X	     *	Mouse Acceleration
X	     */
X	    {
X		register short n;
X		register short s;
X
X		if (dms->Acc != 1) {
X		    n = ev->ie_X;
X		    s = 1;
X		    if (n < 0) {
X			n = -n;
X			s = -1;
X		    }
X		    if (n > dms->AThresh)
X			ev->ie_X = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
X		    n = ev->ie_Y;
X		    s = 1;
X		    if (n < 0) {
X			n = -n;
X			s = -1;
X		    }
X		    if (n > dms->AThresh)
X			ev->ie_Y = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
X		}
X	    }
X
X	    /*
X	     *	Auto Activate and LMB (win/scrn front/bak)
X	     */
X
X	    if (dms->LMBEnable && ev->ie_Code == IECODE_RBUTTON && (ev->ie_Qualifier & dms->RQual))
X		ev->ie_Class = IECLASS_NULL;	/*  remove event    */
X	    if (NRMe == 0 && ((dms->AAEnable & 1) || dms->LMBEnable)) {
X		register short old;
X		NRMe = 1;
X		if (ev->ie_Code != IECODE_NOBUTTON)
X		    old = SetTaskPri(dms->Port.mp_SigTask, 21);
X		sendrequest(REQ_RAWMOUSE, ev);
X		if (ev->ie_Code != IECODE_NOBUTTON)
X		    SetTaskPri(dms->Port.mp_SigTask, old);
X	    }
X	    break;
X	case IECLASS_RAWKEY:
X	    /*
X	     *	Keyboard events will kill the screen timeout but not
X	     *	the mouse timeout.  Note that the priority of the
X	     *	co-process must be upped to ensure it is able to make the
X	     *	window active before the keystroke is passed further.
X	     *
X	     *	key releases are ignored
X	     *
X	     *	note: ie_Qualifier may or may not have bit 15 set
X	     */
X	    if (ev->ie_Code & 0x80)
X		break;
X	    if (dms->AAEnable & 2) {
X		register short old = SetTaskPri(dms->Port.mp_SigTask, 21);
X		sendrequest(REQ_RAWKEY, ev);
X		SetTaskPri(dms->Port.mp_SigTask, old);
X	    }
X	    STime = ev->ie_TimeStamp.tv_secs + dms->STo;
X	    if (STimedout) {
X		sendrequest(REQ_SCREENON, ev);
X		if (dms->MTo == 0)
X		    sendrequest(REQ_MOUSEON, ev);
X	    }
X	    STimedout = 0;
X
X	    if (ev->ie_Code == dms->Code && (ev->ie_Qualifier | 0x8000) == dms->Qual) {
X		sendrequest(REQ_DOCMD, ev);
X		ev->ie_Class = IECLASS_NULL;	/*  remove event    */
X	    }
X	    break;
X	case IECLASS_TIMER:
X	    /*
X	     *	On a timer event, if timeout has occured execute the operation
X	     *	and reset the timeout.	Note that this will cause continuous
X	     *	timeouts every STo and MTo seconds... required because at any
X	     *	time Intuition might turn the mouse back on or open a screen or
X	     *	something and I want the blanker's to work in the long run.
X	     */
X	    {
X		register long old;
X		if (dms->Reset) {
X		    dms->Reset = 0;
X		    STime = ev->ie_TimeStamp.tv_secs + dms->STo;
X		    MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
X		}
X		if (dms->STo && (old = STime - ev->ie_TimeStamp.tv_secs) < 0) {
X		    STime = ev->ie_TimeStamp.tv_secs + dms->STo + 10;
X		    STimedout = 1;
X		    MTimedout = 1;
X		    if (old > -10) {
X			sendrequest(REQ_SCREENOFF, ev);
X			sendrequest(REQ_MOUSEOFF, ev);
X		    }
X		}
X		if (dms->MTo && (old = MTime - ev->ie_TimeStamp.tv_secs) < 0) {
X		    MTime = ev->ie_TimeStamp.tv_secs + dms->MTo + 1;
X		    MTimedout = 1;
X		    if (old > -10)
X			sendrequest(REQ_MOUSEOFF, ev);
X		}
X	    }
X	    break;
X	}
X    }
X    return(Ev);
X}
X
Xvoid
Xsendrequest(creq, ev)
Xlong creq;
Xreg IE *ev;
X{
X    reg REQ *req = AllocMem(sizeof(REQ), MEMF_PUBLIC);
X
X    if (req) {
X	req->Msg.mn_Node.ln_Name = (char *)creq;
X	req->Msg.mn_ReplyPort = NULL;
X	req->Msg.mn_Length = sizeof(REQ);
X	if (ev) {
X	    req->ie_Class= ev->ie_Class;
X	    req->ie_Code = ev->ie_Code;
X	    req->ie_Qualifier = ev->ie_Qualifier;
X	    req->ie_TimeStamp = ev->ie_TimeStamp;
X	}
X	PutMsg(&Dms->Port, (MSG *)req);
X    }
X}
X
XLAYER *
XWhichMouseLayer()
X{
X    register struct IntuitionBase *ib = IBASE;
X    register LAYER *layer = NULL;
X    register SCR *scr = ib->FirstScreen;
X
X    for (scr = ib->FirstScreen; scr; scr = scr->NextScreen) {
X	register short mousey = ib->MouseY;
X	register short mousex = ib->MouseX;
X	if (!(scr->ViewPort.Modes & LACE))
X	    mousey >>= 1;
X	if (!(scr->ViewPort.Modes & HIRES))
X	    mousex >>= 1;
X	if (layer = WhichLayer(&scr->LayerInfo, mousex, mousey - scr->ViewPort.DyOffset))
X	    break;
X	if (mousey >= scr->ViewPort.DyOffset)
X	    break;
X    }
X    return(layer);
X}
X
X
SHAR_EOF
echo "extracting dmouse-ipc.doc"
sed 's/^X//' << \SHAR_EOF > dmouse-ipc.doc
X
X    Talking to DMouse.
X
X    DMouse listens on the "DMouse.ipc" port.  To send a message, setup an
X    IORequest structure with the appropriate command and then
X    FindPort()/PutMsg() atomically, then wait for the request to be returned
X    to the reply port specified in the request.
X
X    *** REFER TO THE EXAMPLE BLANKER.C FOR USAGE
X
X    DMCMD_MOUSEON	turn on mouse	    (io_Command 0x80)
X    DMCMD_MOUSEOFF	turn off mouse			0x81
X    DMCMD_SCREENON	turn on screen			0x82
X    DMCMD_SCREENOFF	turn off screen 		0x83
X
X    DMCMD_ADDHANDLER	io_Message.mn_ReplyPort 	0x84
X			contains port to send
X			msgs to.
X
X    DNCMD_REMHANDLER	io_Message.mn_ReplyPort 	0x85
X			contains port to stop
X			sending msgs to.
X
X    DNCMD_PLEASEREMOVE	(DMouse->blanker)               0x86
X
X
X    DNCMD_ADDHANDLER:
X	io_Unit contains a magic cookie used to identify the handler and should
X	be set to some unique memory address (no accesses are actually made,
X	its just an identifier.
X
X	io_Flags contains a bitmap of things our blanker can handle:
X	0x03	we can handle mouse blanking
X	0x0C	we can handle screen blanking
X	0x0F	we can handle both
X
X	The request is NOT returned until you send a DNCMD_REMHANDLER request.
X	If DMouse is killed it will sent a DNCMD_PLEASEREMOVE (0x86) packet to
X	all active handlers and expect them to remove their handlers with a
X	DNCMD_REMHANDLER request.
X
X	NOTE:	You may run multiple blankers.	DMouse will send requests to
X	ALL active handlers.
X
X    DNCMD_REMHANDLER:
X	io_Unit contains a magic cookie that identifies which handler to remove.
X	The request is returned and then the original DNCMD_ADDHANDLER request
X	will be returned to you.  You can still receive DMouse commands up until
X	you finally get the original DNCMD_ADDHANDLER request back.
X
X	on return, io_Error is 0 on success, -1 on failure.
X
X    DNCMD_PLEASEREMOVE:
X	DMouse sends this to you asking you to remove your handler.  If you
X	receive this packet you must remove your handler with DNCMD_REMHANDLER.
X
X
X    DNCMD_MOUSEON,MOUSEOFF,SCREENON, SCREENOFF and PLEASEREMOVE commands
X    will be sent to the port specified in DNCMD_ADDHANDLER while it is
X    active and are expected to be returned to the DMouse handler.  You can
X    differentiate packets sourced by DMouse and packets sourced by you by
X    looking at the mn_Node.ln_Type field.  If it is NT_MESSAGE it was
X    sourced by DMouse, else it was sourced by you and replied by DMouse.
X
X
SHAR_EOF
echo "extracting dmouse.c"
sed 's/^X//' << \SHAR_EOF > dmouse.c
X
X/*
X *  DMOUSE.C	V1.20  3 August 1989
X *
X *  (c)Copyright 1989 by Matthew Dillon, All Rights Reserved
X *
X *  DMOUSE QUIT
X *  DMOUSE -a# -t# -s# -m# -c# -p# -w# -Ln -lqqqq -Rqqqq -An -Kcccc -Qqqqq -C cmd
X *	   -d#
X *
X *  -a#     # = acceleration, default 3.	1 to disable
X *  -t#     # = mouse threshold before acceleration takes effect, def. 0
X *		(in pixels/event)
X *  -s#     # = screen timeout, default 5min,	0 to disable
X *  -m#     # = pointer timeout, default 5 secs,0 to disable
X *  -c#     # = # of clicks to bring window to front
X *  -p#     # = input device priority
X *  -w#     1 = Use WindowToFront()/WindowToBack()  else    (workbench users)
X *	    0 = Use UpFrontLayer(), etc...                  (cli users)
X *  -L0     Disable LeftMouseButton->WindowToFront (LMB+RMB->ToBack)
X *  -L1     Enable it
X *  -lqqqq  Set qualifier + LMB for Window to front (default none)
X *  -Rqqqq  Set qualifier + RMB for Window/ScreenToBack (default LMB)
X *  -A0     Disable Auto-Activate window on mouse move
X *  -A1     Enable it, keyhit-auto-activate disabled	(bit 0 = mouse aa)
X *  -A3     Enable it, keyhit-auto-activate enabled	(bit 1 = key aa)
X *  -Kcccc  Set key code in hex that activates cmd, def is escape
X *  -Qqqqq  Set key qualifier in hex for keycode, def is left-amiga
X *  -C cmd  Set command (must be last option on command line), def NewCli
X *
X *  -d#     Debug mode	(if compiled in)
X */
X
X#include <stdio.h>
X#include "dmouse.h"
X
X#define VERSION 20
X
X#ifdef LATTICE
X#include <dos.h>
X#include <stdlib.h>
X#include <string.h>
X
Xint __stdargs CXBRK(void);
X
X__stdargs	/*  bug in lcr.lib  */
XCXBRK()
X{
X    return(0);
X}
X
X#else
Xextern int Enable_Abort;    /*	CLI break enable	*/
X#endif
X
Xlong	ahtoi ARGS((char *));
Xvoid	main ARGS((int, char **));
X
Xvoid
Xmain(ac, av)
Xint ac;
Xchar *av[];
X{
X    reg short i, j, len;
X    reg long val;
X    reg char *ptr;
X    reg DMS  *dms = (DMS *)FindPort(PORTNAME);
X    short   exists = (dms != NULL);
X    short   create = (dms == NULL);
X    short   quit = 0;
X
X#ifndef LATTICE
X    Enable_Abort = 0;
X#endif
X    if (create) {
X	dms = AllocMem(sizeof(DMS), MEMF_PUBLIC|MEMF_CLEAR);
X	dms->IPri = 51;
X	dms->Version = VERSION;
X	dms->Acc = 3;
X	dms->STo = 5*60;
X	dms->MTo = 5;
X	dms->Code = 0x45;
X	dms->Qual = 0x8040;
X	dms->RQual= 0x4000;
X	dms->Clicks = 1;
X	dms->CLeft = dms->Clicks;
X	strcpy(dms->Cmd, "newcli");
X	dms->LMBEnable = 1;
X	dms->AAEnable = 3;
X	dms->NoSprData = AllocMem(12, MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
X	dms->NoSprData[0] = 0xFE00;
X	dms->NoSprData[1] = 0xFF00;
X    }
X
X    for (i = 1; i < ac; ++i) {
X	ptr = av[i];
X	if (strcmp(ptr, "QUIT") == 0 || strcmp(ptr, "quit") == 0) {
X	    quit = 1;
X	    create = 0;
X	    break;
X	}
X	val = atoi(ptr+2);
X	if (*ptr != '-')
X	    goto def;
X
X	switch(ptr[1]) {
X	case 'd':
X	    dms->Debug = val;
X	    break;
X	case 'a':
X	    dms->Acc = val;
X	    break;
X	case 'c':
X	    if (val < 1)
X		val = 1;
X	    dms->Clicks = dms->CLeft = val;
X	    break;
X	case 'w':
X	    dms->Workbench = val;
X	    break;
X	case 'p':
X	    dms->IPri = val;
X	    break;
X	case 't':
X	    dms->AThresh = val;
X	    break;
X	case 's':
X	    dms->STo = val;
X	    break;
X	case 'm':
X	    dms->MTo = val;
X	    break;
X	case 'L':
X	    dms->LMBEnable = val;
X	    break;
X	case 'l':
X	    dms->LQual = ahtoi(ptr+2);
X	    break;
X	case 'R':
X	    dms->RQual = ahtoi(ptr+2);
X	    break;
X	case 'A':
X	    dms->AAEnable = val;
X	    break;
X	case 'K':
X	    dms->Code = ahtoi(ptr+2);
X	    break;
X	case 'Q':
X	    dms->Qual = ahtoi(ptr+2) | 0x8000;
X	    break;
X	case 'S':
X	case 'M':
X	    puts("-S and -M options obsolete");
X	    break;
X	case 'C':
X	    for (len = strlen(ptr+2) + 2, j = i + 1; j < ac; ++j)
X		len += strlen(av[j]) + 1;
X	    strcpy(dms->Cmd, ptr + 2);
X	    for (j = i + 1; j < ac; ++j) {
X		if (dms->Cmd[0])
X		    strcat(dms->Cmd, " ");
X		strcat(dms->Cmd, av[j]);
X	    }
X	    i = ac;
X	    break;
X	default:    def:
X	    puts("DMOUSE QUIT  or");
X	    puts("DMOUSE -a# -t# -s# -m# -Ln -Rqqqq -An -Kcccc -Qqqqq -C cmd");
X	    printf("DMouse (c)Copyright 1989, Matthew Dillon, All Rights Reserved\nV1.%02d, 3 August 1989\n\n", VERSION);
X	    puts("Freeware, redistributable for non-profit only");
X	    puts("  -a#     Acceleration (default 3)");
X	    puts("  -t#     Accel. threshold (default 0)");
X	    puts("  -s#     Screen timeout (default 300)");
X	    puts("  -m#     Mouse timeout (default 5)");
X	    puts("  -c#     Set # of clicks for wintofront (default 1)");
X	    puts("  -p#     # = input device priority");
X	    puts("  -w#     0 = use UpFrontLayer().. 1 = use WindowToFront()");
X	    puts("  -L0/1   LMB disable/enable (default 1=enabled)");
X	    puts("  -lqqqq  LMB qualifier wintofront (default 0=none)");
X	    puts("  -Rqqqq  RMB qualifier wintoback (default 4000=LMB)");
X	    puts("  -A0-3   Auto-Activate Window disable/enable. B0=mouse B1=keyboard");
X	    puts("  -Kcccc  Command Key Code, default 45 = esc");
X	    puts("  -Qqqqq  Command Key Qualifier, default 40 = Left Amiga");
X	    puts("  -C cmd  cmd to run, must be last option");
X	    puts("Note: LMB(or -R qualifier)(hold)+RMB = WindowToBack");
X	    puts("\n");
X	    puts("Additionaly, Most options may be modified while DMOUSE is active");
X	    create = 0;
X	    i = ac;
X	    break;
X	}
X    }
X    dms->Reset = 1;
X    if (!exists && create) {
X	PROC *proc;
X	printf("Installing DMouse, ");
X	fflush(stdout);
X	dms->Port.mp_Flags = PA_IGNORE;
X	dms->Port.mp_Node.ln_Pri = 0;
X	dms->Port.mp_Node.ln_Type= NT_MSGPORT;
X	dms->Port.mp_Node.ln_Name= AllocMem(sizeof(PORTNAME), MEMF_PUBLIC);
X	strcpy(dms->Port.mp_Node.ln_Name, PORTNAME);
X	NewList(&dms->Port.mp_MsgList);
X	dms->Segment = (long)LoadSeg("l:DMouse-Handler");
X	if (!dms->Segment)
X	    dms->Segment = (long)LoadSeg("DMouse-Handler");
X	if (!dms->Segment) {
X	    puts("Unable to find L:DMouse-Handler");
X	    FreeMem(dms->Port.mp_Node.ln_Name, sizeof(PORTNAME));
X	    create = 0;
X	} else {
X	    AddPort(&dms->Port);
X	    dms->ShakeTask = FindTask(NULL);
X	    dms->ShakeSig = AllocSignal(-1);
X	    proc = (PROC *)CreateProc(dms->Port.mp_Node.ln_Name, 1, dms->Segment, 4096);
X	    Wait(1 << dms->ShakeSig);
X	    FreeSignal(dms->ShakeSig);
X	    exists = 1;
X	    quit = dms->StartupError;
X	    if (quit)
X		puts("Handler error");
X	    else
X		printf("ok.  DMouse V1.%02d, by Matthew Dillon.\n(c)Copyright 1989, Matthew Dillon, All Rights Reserved\n", VERSION);
X	}
X    }
X    if (quit) {
X	if (exists) {
X	    printf("Removing, ");
X	    fflush(stdout);
X	    dms->ShakeTask = FindTask(NULL);
X	    dms->ShakeSig = AllocSignal(-1);
X	    Signal(dms->HandTask, SBF_C);
X	    Wait(1 << dms->ShakeSig);
X	    FreeSignal(dms->ShakeSig);
X	    RemPort(&dms->Port);
X	    FreeMem(dms->Port.mp_Node.ln_Name, sizeof(PORTNAME));
X	    UnLoadSeg(dms->Segment);
X	    puts("ok");
X	}
X	exists = 0;
X	create = 0;
X    }
X    if (!exists) {
X	FreeMem(dms->NoSprData, 12);
X	FreeMem(dms, sizeof(DMS));
X    }
X}
X
Xlong
Xahtoi(str)
Xreg char *str;
X{
X    reg long val = 0;
X    reg char c;
X    while (c = *str) {
X	val <<= 4;
X	if (c >= '0' && c <= '9')
X	    val |= (c & 15);
X	else
X	    val |= (c & 15) + 9;
X	++str;
X    }
X    return(val);
X}
X
X
SHAR_EOF
echo "extracting dmouse.doc"
sed 's/^X//' << \SHAR_EOF > dmouse.doc
X
XV1.20			   DMOUSE.DOC	       3 August 1989
X
X			  Matthew Dillon
X			  891 Regal Rd
X			  Berkeley, California 94708
X			  USA
X
X	DMouse (c)Copyright 1989 by Matthew Dillon, All Rights Reserved
X
X	Refer to BLANKER.DOC and DMOUSE-IPC.DOC for information on external
Xscreen blankers.
X
X	NOTES:	* dres.library no longer required.
X		* IPC mechanism changed
X
X	WORKBENCH USERS:    PLEASE READ THE REVISION HISTORY FOR V1.09 FOR
XPARTIAL SOLUTION TO INTUITION WINDOWTOFRONT() BUG.
X
X	YAIH (Yet Another Input Handler)... nahh, like DMouse better...
Xfor "Dillon's Mouse"???  V1.20 and beyond are no longer in public domain,
Xbut copyright to me.  They are still 'freeware'.
X
X	After looking at and rejecting several mouse-intuition input
Xhandler enhancers (you know, accelerate the mouse, click-to-front, etc...)
Xand finding them all useless, I have written my own.
X
X	- Any option can be turned on or off at any time.
X
X	- Screen blanks if keyboard or mouse is idle > N1 secs (default 300)
X	    (mouse also blanks even if mouse blanking not turned on) One
X	    can install a more sophisticated screen blanker (e.g. one that
X	    brings up a pattern or something) if they wish.
X
X	- The Pesky Mouse blanks if mouse is idle > N2 secs (def 5)
X
X	- Auto Activate a window when the mouse is moved over it.  Window
X	  also activated (if not already active) when you type.  These
X	  two features may be turned on/off independantly
X
X	- Mouse Accelerator.  Back feeds power into the mouse unit;
X	  give it a nudge and it is guarenteed to penetrate up to an
X	  inch and a half of wall plaster (programmable depth).  Once
X	  you start using it, you won't be able to switch back!
X
X	- Programmable command-key and command string ala PopCli, default
X	  left-Amiga ESC.
X
X	- Left Mouse Button click in window brings it to the front
X	    DOES NOT BRING THE WINDOW TO THE FRONT IF IT IS ALREADY
X	    IN THE FRONT.  Other programs would call WindowToFront() on
X	    every click, which is horrible if you have a simple-refresh
X	    window.  WindowToFront() is NOT called for backdrop windows!
X
X	    The qualifier along with the LMB is now settable with the -l option.
X
X	  # clicks required is settable.
X
X	- Hold LMB, click Right Mouse Button .. Window to Back!  Great
X	  for cycling windows.	See next feature for more info.
X
X	  (the qualifier, normally the left mouse button, can be set with
X	   the -R option).
X
X	- Same sequence as above, but if there is no window under the
X	  current mouse position, there is only one window on the screen,
X	  or the window under the mouse is a BACKDROP window, the
X	  sequence cycles through Screens!
X
X	- NO DAMN CLOCK.  Use another utility to get a clock.  No other
X	  glossy thrills.  DMouse is short, sweet, and functional.
X
X	- Does not use a CLI, should be placed in your startup-sequence.
X	  DO NOT 'RUN' DMOUSE!
X
XINSTALLATION:
X
X    Place dmouse-handler in L: (or in the 'current' directory when DMOUSE
X    is run).
X
X    WORKBENCH USERS!!!!!!!!!!	There appears to be a bug in intuition's
X    WindowToFront() call, which can lock up intuition when workbench
X    icons are active.  Under the defaults, this will occur whenever you
X    depress the left mouse button over an icon.
X
X    A partial fix is in place V1.07 and beyond.  However, if you find
X    it still freezing up, the problem can be avoided as follows:  Either
X    turn off the left-mouse-button window- to-front feature (-L0) or leave
X    it on and set the number of clicks required to 2 (-c2) (and don't use
X    the feature while your mouse is over an icon).  V1.09 gives you yet
X    a THIRD option which is even more preferable ... change the qualifier
X    that goes along with the left mouse button to something other than 0,
X    like 3 (either shift). -l3
X
X    BLANKER:	To use a third party blanker (currently only the example at
X    this time) just run it in the background after you run dmouse.
X
X
XEXECUTE FROM A CLI (e.g. WORKBENCH STARTUP SCRIPT), example:
X
X    1> dmouse -c2 -l0 -C c:newshell "<nil: >nil: newcon:320/120/320/80/Shell"
X
X    There is no need to 'RUN' DMouse.  A double set of quotes may be
X    required for the program to work properly with ConMan.
X
X    NOTE:   The shell startup script should immediately CD somewhere.  DMouse
X	    does not remember the cli's path.
X
XTO KILL:
X
X    1> dmouse QUIT
X
XIPC SUPPORT:
X
X    IPC support has changed radically due to removal of dres.library from
X    the required list.	The reason for the change is that I have been getting
X    my programs to compile under both Lattice and Aztec and did not want to
X    port dres.library to Lattice C.
X
X    Please refer to the example blanker programs and dmouse-ipc.doc for
X    more information.
X
X
XSOURCE:
X
X    Source is compileable under Aztec, +L (32 bit ints) and suitable
X    precompiled include file (remember the precompiled include file must
X    be precompiled with +L also).  Use the c32.lib library (Aztec C)
X
X    Source is also compileable under Lattice C V5.02 and beyond.
X
X    You need a working sup32.lib library to compile DMouse.  The library
X    source also includes the local/*.h includes and DMakefiles for making
X    precompiled include files.
X
XCOMMAND LINE ARGUMENTS:
X
X    If DMouse is already running, any specified options will be
X    incorporated.
X
X    quit	QUIT .. remove DMouse
X    -h		HELP
X    -a# 	Set acceleration to #.	Default 3,	     1 disables option
X    -t# 	Set mouse acceleration threshhold, pixs/ev. default 0.
X    -s# 	Set screen timeout to # (secs), Default 300, 0 disables option
X    -m# 	Set mouse timeout to # (secs), Defalut 5,    0 disabled option
X    -c# 	Set # of clicks required to bring window to front (def 1)
X    -p# 	Set input handler priority (def 51) should always be > 50
X		(initial invocation only)
X
X    -w# 	0 = use UpFrontLayer() etc... 1 = use WindowToFront() etc...
X		WindowToFront() properly refreshes SIMPLE_REFRESH windows
X		but a bug intuition can cause it to crash the machine if
X		a workbench icon is active at the time.
X
X    -L0/1	Disable/Enable left-button brings window to front
X    -A0-3	Disable/Enable AUTO-ACTIVATE. Bit #0 = mouse auto-activate
X						  #1 = keyboard auto-activate
X		    (default 3, which enables both)
X
X    -lqqqq	Set Qualifier (HEX) with LMB for Window To Front (default is
X		 0, meaning no qualifier).  Example:	-l0003 sets it to
X		 either shift key.
X
X    -Rqqqq	Set Qualifier (HEX) with RMB for Window To Back (default is
X		 the LMB qualifier).  Setting the qualifier to 0 disables
X		 the feature.
X
X    -Kcccc	Set Keycode (HEX)   for command key (default 0045)
X
X    -Qqqqq	Set Qualifier (HEX) for command key (default 0040)
X
X    -C CMD	Set Command to run.  Default is NEWCLI.  Remaining arguments
X		on command line is the command.
X
X    -S/-M	REMOVED.  Obsoleted by new IPC mechanism.
X
X			QUALIFIERS (always entered in HEX)
X
X    0001    Left Shift
X    0002    Right Shift
X    0004    Caps Lock
X    0008    Control
X    0010    Left Alt
X    0020    Right Alt
X    0040    Left Amiga Key
X    0080    Right Amiga Key
X    0100    Numeric Key Pad Key (not useful for dmouse)
X    0200    Repeat		(not useful for dmouse)
X    0400    Interrupt		(not useful for dmouse)
X    0800    Multibroadcast	(not useful for dmouse)
X    1000    Middle Mouse Button (not normally implemented by intuition)
X    2000    Right Mouse Button
X    4000    Left Mouse Button
X
X	Note:	Combinations are allowed, in which case any one of the
X		selected qualifiers along with the left, right mouse button
X		or command key will cause the appropriate action to occur.
X
X
XRELEASE HISTORY:
X
XV1.20
X    -3rd party IPC mechanism fixed.  A new mechanism is now in place.
X
XV1.16
X    -Code fixed to compile under either Manx C 3.6 or Lattice C 5.02
X    -3rd party screen blanker supported removed due to removal of
X     dnet.library (which is too difficult to port at this time).
X
XV1.14
X    -minor bug fixes.  DLineArt added to distribution (removed again in
X     1.16 temporarily)
X
XV1.13
X    -d option (debug mode if compiled in) not compiled in on release
X       binaries
X    -You can now bring up a new cli without having to move the mouse from
X     its initial (power up) position.
X    -Checks if the copper list stuff it modifies is valid.  If not, does
X     not modify the copper list stuff (you loose mouse blanking instead of
X     crashing the machine for those using the hires board)
X
X
XV1.12
X    -S option added, external screen blanker supported.
X    -M option added, external mouse blanker supported.
X    -IPC commands changed to 'mouse on/off' 'screen on/off', they used
X     to be 'mouse / nomouse' and 'blank / noblank'.
X
XV1.11
X    -Intelligent requester handling: auto-activate is disabled while the
X     active window has a requester in it.  Slight modification of key
X     handling (key-up events are ignored by DMouse).  Addition of
X     text-based IPC to blank/unblank the mouse/screen.
X
XV1.10
X    -Fixed -A bug ... -A2 now enables auto-activate-on-key and disables
X     auto-activate-on-mouse
X
XV1.09
X
X    Workbench users probably want to use the following options: -w1 -l0003
X    These use WindowToFront() (your windows get refreshed properly), but
X    also requires you to depress a shift key + LMB to get the window-to-front
X    feature.
X
X	dmouse -w1 -l0003
X
X    -SELECTABLE USE OF UpFrontLayer() etc..  OR  WindowToFront() etc...
X     Workbench users should use WindowToFront() (-w1), while CLI users
X     probably want to use UpFrontLayer() (default).
X
X     Reason:	WindowToFront()/Back can crash the Amiga if called while
X     a workbench ICON is highlighted.  Unfortunetly, UpFrontLayer(), which
X     does not have the bug, also does not automatically refresh
X     simple-refresh windows!
X
X    -New option -lqqqq (SET QUALIFIER WITH LEFT MOUSE BUTTON TO GET
X     WINDOW-TO-FRONT FEATURE).	WORKBENCH USERS NOTE:  By setting this
X     qualifier to a shift key, for instance, you can safely move icons
X     around without crashing the machine because DMouse will not issue
X     the WindowToFront() call unless you are holding the qualifier key
X     down while pressing the left mouse button.
X
X    -Bug fixed thanks to user persistance!  If you disable mouse blanking,
X     and enable screen blanking (which blanks the mouse too when it
X     happens), hitting a key would bring back the screen but not the mouse.
X
XV1.08
X     Botched.
X
XV1.07
X    -All intuition calls are made from an independant process rather than
X     the input handler routine.  This also fixes a couple of deadlock bugs,
X     but not the workbench-icon deadlock bug.
X    -Mouse response is no longer jerky when the system is loaded down.
X    -Keyboard-Auto-Activate-Window independant of Mouse-Auto-Activate-Window
X     (enhanced -A option)
X    -No need to OR the -Q qualifier with 8000 anymore
X    -WindowToFront() never called for backdrop windows, which ought to fix
X     the workbench freeze bug and other problems.
X    -Mouse automatically blanked when screen blanks, whether mouse blanking
X     is enabled or not.
X    -Can set input handler priority (initial invocation only).
X    -New Timeouts go into effect immediately rather than after the
X     next mouse/keyboard event.
X
XV1.00-V1.06
X    Before Written history
X
X
SHAR_EOF
echo "extracting dmouse.h"
sed 's/^X//' << \SHAR_EOF > dmouse.h
X
X/*
X *  DMOUSE.H
X */
X
X#include <local/typedefs.h>
X
X#define DMS struct _DMS
X#define REQ struct _REQ
X
X#define PORTNAME    "DMouse"
X
X#define REQ_SCREENON	-1
X#define REQ_SCREENOFF	-2
X#define REQ_MOUSEON	-3
X#define REQ_MOUSEOFF	-4
X#define REQ_DOCMD	-5
X#define REQ_RAWMOUSE	-6
X#define REQ_RAWKEY	-7
X#define REQ_DEBUG	-8
X#define REQ_DEBUGOFF	-9
X
X#define SBF_C	SIGBREAKF_CTRL_C
X#define SBF_D	SIGBREAKF_CTRL_D
X#define SBF_E	SIGBREAKF_CTRL_E
X#define SBF_F	SIGBREAKF_CTRL_F
X
Xtypedef struct IOStdReq     IOR;
Xtypedef struct Interrupt    INT;
Xtypedef struct timeval	    TS;
Xtypedef void		    (*FPTR)();
X
X
XDMS {
X    PORT    Port;
X    short   Version;
X    short   Acc;
X    short   AThresh;
X    long    STo;
X    long    MTo;
X    uword   Code;
X    uword   Qual;
X    uword   RQual;	    /*	Right button qualifier	*/
X    uword   LQual;	    /*	Left button qualifier	*/
X    char    Cmd[256];
X    char    LMBEnable;
X    char    AAEnable;
X    char    IPri;
X    char    FSEnable;	    /*	Foreign Screen Enable	*/
X    char    Workbench;	    /*	Use WindowToFront/Back	*/
X    char    Debug;	    /*	Debug Mode		*/
X    char    Reserved3;
X    TASK    *HandTask;
X    TASK    *ShakeTask;
X    short   ShakeSig;
X    short   StartupError;
X    uword   *NoSprData;
X    long    Segment;
X
X    uword   Clicks;	/*  # clicks required		*/
X    uword   CLeft;	/*  # clicks left to do 	*/
X    TS	    CTime;	/*  time of last click		*/
X    WIN     *CWin;	/*  All clicks in same window	*/
X    char    Reset;	/*  Option modified, reset tos	*/
X
X    char    *MRemote;	/*  Remote mouse blanker (obsolete) */
X    char    *SRemote;	/*  Remote screen blanker(obsolete) */
X    long    DLock[2];	/*  synchronizing lock	 (obsolete) */
X};
X
XREQ {
X    MSG     Msg;
X    TS	    ie_TimeStamp;
X    ubyte   ie_Class;
X    uword   ie_Code;
X    uword   ie_Qualifier;
X};
X
X
SHAR_EOF
echo "End of archive 1 (of 1)"
# if you want to concatenate archives, remove anything after this line
exit