[comp.os.minix] Mouse information/bibliography

pcm@iwarpr0.intel.com (Phil Miller) (12/04/89)

I got a request for a list of books which describe interfaces to mouses
(sic, that's really the right word).  Here are some:

Books:
	"The Programmer's PC Sourcebook", by Thom Hogan.  Microsoft Press.
	Good tables of BIOS-level interfacing information (MS-DOS, of
	course).  Much of this information appears (free) from time to
	time in the newsgroup "comp.binaries.ibm.pc" in the interrupt list.

	"Advanced MS-DOS Programming, Second Edition", Ray Duncan, MS Press.

	"MS-DOS Extensions", Ray Duncan, Microsoft Press, Programmer's
	Quick Reference Series.

	"The Microsoft Mouse User's Guide", author unk, presumably pub.
	by Microsoft Press.

	There is another another book my MS Press, Title unk, author unk,
	which comes with a disk and has quite a bit of useful interfacing
	stuff in it.  It's recent, probably 1989.

	"Logitech Mouse User's Manual", Logitech Inc. Publications Dept.

	"Logitech Mouse Technical Reference Manuals", Logitech Inc.
	Publications Dept. Logitech sales number: (800)552-8885 in
	California, (800)231-7717 otherwise.

	"Advanced Turbo C Programmer's Guide", Donna Mosich, Namir Shammmas,
	and Bryan Flamig.  Wiley Publishing.

Magazines:

	"Mouse Interrupts", by Nigel Cort.  Spring and Summer '88 issues,
	The C Gazette, published by Pacific Data Works, 1341 Ocean Avenue #257,
	Santa Monica, CA 90401-1066.

	(title unknown), Kent Porter, May/June (year unk) Turbo Technix,
	from Borland (the Turbo C people).

However, the information in question is a bit hard to extract from most of
the readily available sources, not to mention the fact that they're all DOS
stuff, so here's the source code to a mouse driver which was written for
Microport System V/{2,3}86.  This appeared in the Microport newsgroup a year
or two back.  I think the necessary information can be inferred from the
program.  The program below was written by people at Microport, and they
placed it in the public domain.


Phil Miller
pcm@iwarp.intel.com


========================== cut here ==========================


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  mouse.c mouse.h tst.c
# Wrapped by gis@dlvax2 on Fri Jul 21 10:23:41 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'mouse.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mouse.c'\"
else
echo shar: Extracting \"'mouse.c'\" \(2632 characters\)
sed "s/^X//" >'mouse.c' <<'END_OF_FILE'
X/*
X * Simple mouse driver for the Logitech Bus Mouse
X * Mouse deltas and button state is accessed through an ioctl()
X *
X *	Written By
X *	John Plocher
X *	Jas Cluff
X *	Ken Chapin
X *
X *	This code is released into the Public Domain
X */
X
X/*
X**	Compile with    cc -Ml -c mouse.c	V/286  (V/AT)
X**			cc     -c mouse.c	V/386  (3.0 or 3.2)
X**
X**	Install in the kernel configuration directories
X**	generate a kernel & reboot off of it
X**	run the tst program to test out behavior
X*/
X
X#include	"sys/param.h"
X#include	"sys/types.h"
X#include	"sys/dir.h"
X#include	"sys/signal.h"
X#include	"sys/user.h"
X#include	"sys/errno.h"
X#include	"mouse.h"
X
X#ifdef DEBUG
X#  define Dprintf(string)	printf(string)
X#else
X#  define Dprintf(string)
X#endif
X
Xmsinit()
X{
X	/*	Is mouse there?		*/
X
X/* Test hardware registers to see if installed       TODO */
X
X	/*	Initailize registers	*/
X	outb(CONTROL, MOUSEDEFAULT);
X	outb(PORTC, PORTC_DISABLE_INTERRUPTS);
X
X	/*      Say hello world         */
X#ifdef USE_INTS
X	printf("ms 1.01 %x-%x %x Ints are used\n",
X#else
X	printf("ms 1.01 %x-%x %x No ints for now\n",
X#endif
X			PORTA, CONTROL, inb(SIGNATURE_PORT));
X}
X
Xmsstart()
X{
X	Dprintf("MSSTART\n");
X}
X
Xmsopen()
X{
X	Dprintf("MSOPEN\n");
X	/*	Enable interrupts	*/
X#ifdef USE_INTS
X	outb(PORTC, PORTC_ENABLE_INTERRUPTS);
X#endif
X}
X
Xmsclose()
X{
X	/*	Disable interrupts	*/
X	Dprintf("MSCLOSE\n");
X	outb(PORTC, PORTC_DISABLE_INTERRUPTS);
X}
X
Xmsread()
X{
X/* NOP - do nothing but disable interrupt generator on bus mouse board */
X	Dprintf("MSREAD\n");
X	outb(PORTC, PORTC_DISABLE_INTERRUPTS);
X}
X
Xmswrite()
X{
X/* NOP - do nothing but disable interrupt generator on bus mouse board */
X	Dprintf("MSWRITE\n");
X	outb(PORTC, PORTC_DISABLE_INTERRUPTS);
X}
X
Xmsioctl(dev, cmd, arg)
Xint dev, cmd, *arg;
X{
X	/*	Get mouse values for user	*/
X
X	/*
X	** The Bus Mouse board keeps a running delta between reads
X	** so all we do here is send it back to the user when she wants it
X	*/
X
X	register struct mousedat md;
X	register unsigned int i;
X
X	switch(cmd) {
X	case MIOGETDATA:outb(PORTC, READ_X_LOW);
X			md.deltax = inb(PORTA) & 0xf;
X			outb(PORTC, READ_X_HIGH);
X			md.deltax |= (inb(PORTA) & 0xf) << 4;
X
X			outb(PORTC, READ_Y_LOW );
X			md.deltay = inb(PORTA) & 0xf;
X			outb(PORTC, READ_Y_HIGH);
X			i = inb(PORTA);
X			outb(PORTC, PORTC_DISABLE_INTERRUPTS);
X			md.deltay |= (i & 0xf) << 4;
X			md.buttons = i >> 5;
X
X			if (copyout(&md, arg, sizeof md))
X				u.u_error = EFAULT;
X			break;
X
X	default:	u.u_error = EFAULT;
X			break;
X	}
X}
X
Xmsintr()
X{
X
X/*
X** Not Used - might be used to keep a running delta and send a signal to
X** the controlling tty if a button was pressed ....
X*/
X	/*	Respond to squeak	*/
X	Dprintf("M");
X}
X
END_OF_FILE
if test 2632 -ne `wc -c <'mouse.c'`; then
    echo shar: \"'mouse.c'\" unpacked with wrong size!
fi
# end of 'mouse.c'
fi
if test -f 'mouse.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mouse.h'\"
else
echo shar: Extracting \"'mouse.h'\" \(1334 characters\)
sed "s/^X//" >'mouse.h' <<'END_OF_FILE'
X/*	mouse.h:	header file for Logitech Bus Mouse driver	*/
X
X#ifndef MOUSE_H
X#define MOUSE_H
X
X/* #define USE_INTS	/* Should the driver use interrupts? */
X
X#define	PORTA	0x23c		/*	1100		*/
X#define	SIGNATURE_PORT	0x23d	/*	1101		*/
X#define	PORTC	0x23e		/*	1110		*/
X#define	CONTROL	0x23f		/*	1111		*/
X
X#define	SETMODE		0x80	/*	1xxx xxxx	*/
X	/* Group A */
X#define M_AMODE0	0x00	/*	x00x xxxx	*/
X#define M_AMODE1	0x20	/*	x01x xxxx	*/
X#define M_AMODE2	0x40	/*	x10x xxxx	*/
X#define M_AIN		0x10	/*	xxx1 xxxx	*/
X#define M_AOUT		0x00	/*	xxx0 xxxx	*/
X#define M_CUIN		0x08	/*	xxxx 1xxx	*/
X#define M_CUOUT		0x00	/*	xxxx 0xxx	*/
X	/* Group B */
X#define M_BMODE0	0x00	/*	xxxx x0xx	*/
X#define M_BMODE1	0x04	/*	xxxx x1xx	*/
X#define M_BIN		0x02	/*	xxxx xx1x	*/
X#define M_BOUT		0x00	/*	xxxx xx0x	*/
X#define M_CLIN		0x01	/*	xxxx xxx1	*/
X#define M_CLOUT		0x00	/*	xxxx xxx0	*/
X
X#define MOUSEDEFAULT	(SETMODE|M_AMODE0|M_AIN)	/* 1001 0000 */
X
X#define	READ_X_LOW	0x80	/*	1000 0000	*/
X#define	READ_X_HIGH	0xa0	/*	1010 0000	*/
X#define	READ_Y_LOW	0xc0	/*	1100 0000	*/
X#define	READ_Y_HIGH	0xe0	/*	1110 0000	*/
X
X#define	PORTC_ENABLE_INTERRUPTS		0x80	/*	1000 0000	*/
X#define	PORTC_DISABLE_INTERRUPTS	0x10	/*	0000 0000	*/
X
Xstruct	mousedat { 
X	unsigned char buttons; 
X	char deltax,deltay;
X};
X
X/* IOCTLS */
X#define	MIOGETDATA	(('M'<<8) | 0x01)	/* get mouse data */
X
X#endif
X
END_OF_FILE
if test 1334 -ne `wc -c <'mouse.h'`; then
    echo shar: \"'mouse.h'\" unpacked with wrong size!
fi
# end of 'mouse.h'
fi
if test -f 'tst.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tst.c'\"
else
echo shar: Extracting \"'tst.c'\" \(1584 characters\)
sed "s/^X//" >'tst.c' <<'END_OF_FILE'
X
X/*
X**	Test program for Mouse Driver
X*/
X
X/* #define USE_GFX /* Microport 2.4 (286) or 3.0e (386) graphics interface */
X
X#include <sys/io_op.h>
X#include <sys/types.h>
X#ifdef USE_GFX
X#include <gfx.h>
X#endif
X#include "mouse.h"
X
Xint     mousefd;
X
X#ifdef USE_GFX
XGfx_Bitmap bm;
X#endif
X
Xmain()
X{
X	register struct mousedat	new,old;
X	register int xpos, ypos;
X
X	old.deltax = old.deltay = old.buttons = 1;
X
X	if ((mousefd = open("/dev/mouse")) == -1) {
X		perror("open of mouse device");
X		exit(1);
X	}
X
X#ifdef USE_GFX
X	if (!(bm = gfx_open())) {
X		perror("open of gfx");
X		exit(1);
X	}
X	gfx_mode(bm, GRAPHIC);
X	gfx_clear(bm, BLACK);
X	ega_flush();
X#else
X#endif
X
X	xpos = ypos = 1;
X	while (old.buttons != 7) {	/* press all 3 buttons to quit */
X		readmouse(&new);
X		if (memcmp(&old, &new, sizeof(struct mousedat))) {	
X#ifdef USE_GFX
X            gfx_rect(bm,xpos-1, ypos-1,xpos+1, ypos+1,7+old.buttons,GFX_XOR);
X			xpos += new.deltax; ypos += new.deltay;
X            gfx_rect(bm,xpos-1, ypos-1,xpos+1, ypos+1,7+new.buttons,GFX_XOR);
X			ega_flush();
X			memcpy(&old, &new, sizeof(struct mousedat));
X#else
X			xpos += new.deltax; ypos += new.deltay;
X		        printf("X=%03d Y=%03d  Buttons=%c%c%c\n", xpos, ypos,
X				   new.buttons & 1 ? '*' : ' ',
X				      new.buttons & 2 ? '*' : ' ',
X				         new.buttons & 4 ? '*' : ' ' );
X#endif
X		}
X	}
X#ifdef USE_GFX
X	gfx_dot(bm,xpos, ypos, BLACK, GFX_SRC);
X	ega_flush();
X	gfx_mode(bm, ALPHA);
X#else
X#endif
X}
X
Xreadmouse( md )
Xregister struct mousedat *md;
X{
X	if ((ioctl(mousefd, MIOGETDATA, md)) == -1) {
X		perror("IOCTL failed on /dev/mouse");
X		exit(2);
X	}
X}
X
END_OF_FILE
if test 1584 -ne `wc -c <'tst.c'`; then
    echo shar: \"'tst.c'\" unpacked with wrong size!
fi
# end of 'tst.c'
fi
echo shar: End of shell archive.
exit 0

Regards,

Ian Stewartson
Data Logic Ltd.