Path: utzoo!utgpu!water!watmath!clyde!cbosgd!ihnp4!ptsfa!ames!ucbcad!ucbvax!hplabs!hpcea!hpfcdc!stroyan
From: stroyan@hpfcdc.HP.COM (Mike Stroyan)
Newsgroups: comp.sys.amiga
Subject: Re: HELP! (ummm, help?)
Message-ID: <5500007@hpfcdc.HP.COM>
Date: 11 Dec 87 07:58:13 GMT
References: <549@zehntel.UUCP>
Organization: HP Ft. Collins, Co.
Lines: 370

I had the same problem with a program for a Kurta Penmouse+ that used
the same technique.  Adding "SetTaskPri(FindTask(0L), 20L);" cleared
it right up.

I am including the program, which should convert easily to the bitpad
by adjusting the Parse and send_event functions.  The program compiles
with Manx C.

Mike Stroyan, [hplabs!]hpfcla!stroyan


# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by stroyan at hpfcri on Fri Dec 11 00:33:47 1987
#
# This archive contains:
#	makefile	kurta.c		
#

echo x - makefile
cat >makefile <<'@EOF'
CFLAGS=

.c.o:
	cc $(CFLAGS) -o $@ $*.c

kurta: kurta.o
	ln -w -o kurta kurta.o -lc

kurta2: kurta2.o
	ln -w -o kurta2 kurta2.o -lc
@EOF

chmod 664 makefile

echo x - kurta.c
cat >kurta.c <<'@EOF'
/* kurta.c */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

static short done = 0;
static struct IOExtSer *inreq = NULL;
static unsigned char inbuf[513];
static struct MsgPort *inputDevPort = NULL;
static struct MsgPort *timerDevPort = NULL;
static struct IOStdReq *input_request_block = NULL;
static struct timerequest *tr = NULL;
static short input_device_open = 0;
static short timer_device_open = 0;
static struct InputEvent motion_event;
static struct InputEvent button_event;

struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct Window *Window = NULL;


main()
{
	struct NewWindow NewWindow;
	register struct IntuiMessage *msg;

	SetTaskPri(FindTask(0L), 20L);

	/* Open display */
	if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L)))
		CleanUp("no graphics library!!!");
 
	if (!(IntuitionBase = (struct IntuitionBase *)
		OpenLibrary("intuition.library", 0L)))
		CleanUp("no intuition here!!");

	NewWindow.LeftEdge = 250;
	NewWindow.TopEdge = 0;
	NewWindow.Width = 150;
	NewWindow.Height = 10;
	NewWindow.DetailPen = 0;
	NewWindow.BlockPen = 1;
	NewWindow.Title = (UBYTE *) "Kurta";
	NewWindow.Flags = WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH
		| SIMPLE_REFRESH;
	NewWindow.IDCMPFlags = CLOSEWINDOW | REFRESHWINDOW;
	NewWindow.FirstGadget = NULL;
	NewWindow.CheckMark = NULL;
	NewWindow.Type = WBENCHSCREEN;
	NewWindow.Screen = NULL;
	NewWindow.BitMap = NULL;
	NewWindow.MinWidth = 150;
	NewWindow.MinHeight= 10;
	NewWindow.MaxWidth = 150;
	NewWindow.MaxHeight= 10;

	if (!(Window = (struct Window *) OpenWindow(&NewWindow)))
		CleanUp("Couldn't open the window.");

	/* prepare input device */
	inputDevPort = CreatePort(0L, 0L);
	if (inputDevPort == NULL)
		CleanUp("Can't create port");
	input_request_block = CreateStdIO(inputDevPort);
	if (input_request_block == NULL)
		CleanUp("Can't create input request block");
	if (OpenDevice("input.device", NULL, input_request_block, NULL))
		CleanUp("Can't open input device");
	input_device_open = 1;

	input_request_block->io_Command = IND_WRITEEVENT;
	input_request_block->io_Flags = 0;
	input_request_block->io_Length = sizeof(struct InputEvent);

	motion_event.ie_NextEvent = NULL;
	motion_event.ie_Class = IECLASS_POINTERPOS;
	motion_event.ie_Code = IECODE_NOBUTTON;

	button_event.ie_NextEvent = NULL;
	button_event.ie_Class = IECLASS_RAWMOUSE;
	button_event.ie_X = 0;
	button_event.ie_Y = 0;

	/* prepare timer device */
	timerDevPort = CreatePort(0L, 0L);
	if (timerDevPort == NULL)
		CleanUp("Can't create port");
	tr = AllocMem((long) sizeof(*tr), MEMF_CLEAR | MEMF_PUBLIC);
	if (tr == NULL)
		CleanUp("Can't create timer request");
	tr->tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
	tr->tr_node.io_Message.mn_Node.ln_Pri = 0;
	tr->tr_node.io_Message.mn_ReplyPort = timerDevPort;
	if (OpenDevice(TIMERNAME, UNIT_MICROHZ, tr, NULL))
		CleanUp("Can't open timer device");
	timer_device_open = 1;

	tr->tr_node.io_Command = TR_GETSYSTIME;

	/* prepare serial device */
	inreq = (struct IOExtSer *)
		AllocMem((long) sizeof(*inreq), MEMF_PUBLIC | MEMF_CLEAR);
	if (inreq == NULL)
		CleanUp("Can't allocate memory");
	inreq->IOSer.io_Message.mn_ReplyPort = CreatePort("SerialRead", 0L);
	if (inreq->IOSer.io_Message.mn_ReplyPort == NULL)
		CleanUp("Can't create port");
	inreq->io_SerFlags = SERF_XDISABLED;
	if (OpenDevice(SERIALNAME, NULL, inreq, NULL))
		CleanUp("Can't open Serial port");

	inreq->IOSer.io_Command = SDCMD_SETPARAMS;
	inreq->io_ReadLen = inreq->io_WriteLen = 8;
	inreq->io_Baud = 2400;
	DoIO(inreq);

	inreq->IOSer.io_Command = CMD_READ;
	inreq->IOSer.io_Data = (APTR) inbuf;
	inreq->IOSer.io_Length = 1;
	SendIO(inreq);

	while (!done) {
		/* wait for something to do */
		Wait(1L << inreq->IOSer.io_Message.mn_ReplyPort->mp_SigBit
			 | 1L << Window->UserPort->mp_SigBit);
		if (CheckIO(inreq)) { /* received data from the tablet */
			WaitIO(inreq);
			Parse(inbuf, inreq->IOSer.io_Actual);
			inreq->IOSer.io_Command = SDCMD_QUERY;
			DoIO(inreq);
			inreq->IOSer.io_Command = CMD_READ;
			if (inreq->IOSer.io_Actual > 0) {
				inreq->IOSer.io_Length = inreq->IOSer.io_Actual;
				if (inreq->IOSer.io_Length > 512)
					inreq->IOSer.io_Length = 512;
				DoIO(inreq);
				Parse(inbuf, inreq->IOSer.io_Actual);
				inreq->IOSer.io_Length = 1;
			}
			SendIO(inreq);
		}

		while (msg = (struct IntuiMessage *) GetMsg(Window->UserPort)) {
			ReplyMsg(msg);
			switch (msg->Class) {
				case CLOSEWINDOW: /* shut down */
					done = 1;
					break;
				default:
					break;
			}
		}
	}

	CloseDevice(inreq);
	CleanUp(NULL);
}

/*
 * Function to parse data tablet format
 */

Parse(data, count)
unsigned char *data;
ULONG count;
{
	static int byte_index = 1;
	static int x, y, switch2, switch3;

	while (count > 0) {
		switch (byte_index) {
			case 1:
				/* Try to sync up to tablet */
				if ((*data & 0x40) == 0)
					break;
reset:
				switch2 = (*data & (0x10 | 0x08)) != 0;
				switch3 = (*data & 0x04) != 0;
				byte_index = 2;
				break;
			case 2:
				if (*data & 0x40)
					goto reset;
				x = *data & 0x3F;
				byte_index = 3;
				break;
			case 3:
				if (*data & 0x40)
					goto reset;
				x |= (*data & 0x1F) << 6;
				byte_index = 4;
				break;
			case 4:
				if (*data & 0x40)
					goto reset;
				y = *data & 0x3F;
				byte_index = 5;
				break;
			case 5:
				if (*data & 0x40)
					goto reset;
				y |= (*data & 0x1F) << 6;
				send_event(x, y, switch2, switch3);
				byte_index = 1;
				break;
		}
		count -= 1;
		data += 1;
	}
}

send_event(x, y, switch2, switch3)
int x, y, switch2, switch3;
{
	static int old_x = 0, old_y = 0;
	static int old_switch2 = 0, old_switch3 = 0;

	if (x != old_x || y != old_y) {
		input_request_block->io_Data = (APTR) &motion_event;
		motion_event.ie_X = (2 * x) / 3 - 50;
		if (motion_event.ie_X < 0)
			motion_event.ie_X = 0;
		else if (motion_event.ie_X > 640)
			motion_event.ie_X = 640;
		motion_event.ie_Y = 450 - (2 * y) / 3;
		if (motion_event.ie_Y < 0)
			motion_event.ie_Y = 0;
		if (motion_event.ie_Y > 400)
			motion_event.ie_Y = 400;
		motion_event.ie_Qualifier = 
			(old_switch3 ? IEQUALIFIER_LEFTBUTTON : 0) |
			(old_switch2 ? IEQUALIFIER_RBUTTON : 0);

		/* get the current time */
		DoIO(tr);
		motion_event.ie_TimeStamp = tr->tr_time;

		DoIO(input_request_block);

		old_x = x;
		old_y = y;
	}

	if (switch3 != old_switch3) {
		input_request_block->io_Data = (APTR) &button_event;
		button_event.ie_Code = IECODE_LBUTTON;
		if (!switch3)
			button_event.ie_Code |= IECODE_UP_PREFIX;
		button_event.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE |
			(switch3 ? IEQUALIFIER_LEFTBUTTON : 0) |
			(old_switch2 ? IEQUALIFIER_RBUTTON : 0);

		/* get the current time */
		DoIO(tr);
		button_event.ie_TimeStamp = tr->tr_time;

		DoIO(input_request_block);

		old_switch3 = switch3;
	}

	if (switch2 != old_switch2) {
		input_request_block->io_Data = (APTR) &button_event;
		button_event.ie_Code = IECODE_RBUTTON;
		if (!switch2)
			button_event.ie_Code |= IECODE_UP_PREFIX;
		button_event.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE |
			(switch3 ? IEQUALIFIER_LEFTBUTTON : 0) |
			(switch2 ? IEQUALIFIER_RBUTTON : 0);

		/* get the current time */
		DoIO(tr);
		button_event.ie_TimeStamp = tr->tr_time;

		DoIO(input_request_block);

		old_switch2 = switch2;
	}
}

/*
 * Function to clean up however much stuff got started
 */

static CleanUp(text)
char *text;
{
	if (timer_device_open)
		CloseDevice(tr);
	if (tr)
		FreeMem(tr, (long) sizeof(*tr));
	if (timerDevPort)
		DeletePort(timerDevPort);

	if (input_device_open)
		CloseDevice(input_request_block);
	if (input_request_block)
		DeleteStdIO(input_request_block);
	if (inputDevPort)
		DeletePort(inputDevPort);

	if (inreq) {
		if (inreq->IOSer.io_Message.mn_ReplyPort)
			DeletePort(inreq->IOSer.io_Message.mn_ReplyPort);

		FreeMem(inreq, (long) sizeof(*inreq));
	}

	if (Window) CloseWindow(Window);
	if (IntuitionBase) CloseLibrary(IntuitionBase);
	if (GfxBase) CloseLibrary(GfxBase);

	if (text) {
		fprintf(stderr, "ERROR: %s\n", text);
		exit(100);
	}
	exit(FALSE);
}
@EOF

chmod 664 kurta.c

exit 0