honzo@4gl.UUCP (04/11/87)
Some day's ago I asked the Net how the PC Mouse works. It happens to be
quite simple...
From: mcvax!masscomp!alang:
============================================================================
Serial mice normally run at 1200 baud.
When the mouse is moved, or buttons are pressed or released, 5 bytes of
information are sent.
The first byte tells the current button state. The high order 5 bits are the
pattern 10000 with the remaining 3 bits being the sate of the left, middle,
and right mouse buttons.
Bytes 2 and 3 are 8 bit signed values of delta x and delta y.
Bytes 4 and 5 are also 8 bit signed values of delta x and delta y, relative
to the previous two bytes. (ie. use both sets -- not just the first)
I'm not sure, but since you know that the data is being sent at a constant
rate, you might be able to infer the speed at which the mouse was being
moved from the difference between the two sets of x and y.
This information is for the mouse systems mouse, but this appears to have
become a standard amongst serial mice.
Alan Groupe
============================================================================
Thanks Alan! (and of course all the others not mentioned who send mail)
... which means that you can connect this (very cheap) mouse to any spare
serial line! To try the above out, I decided to add a mouse to vi. It does
not work perfect, but shows how you can use the mouse.
This will compile on any Sys V machine. And run on an ANSI type terminal,
provided that you map your keypad to the h j k l keys.
Button 1 send's ESC. Button 2 sends . (again). Button 3 will start the
context senzitive Pull Down Help function, but is not yet finished :-).
(Could be done though, thinking about it, you only need to send a ^L to
restore the Vi screen after you are done)
When your are going to use mvi regularly, I suggest that you remove your
bell from your terminal! (You'll find out why)
Any comments etc are welcome at mcvax!4gl!honzo
------code follows -----
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/[k]sh to create the files:
# Makefile
# mouse.c
# mvi
# This archive created: Sat Apr 11 02:03:41 1987
# By: honzo
export PATH; PATH=/bin:$PATH
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
cat > 'Makefile' << \S!H!A!R
#
all: mouse.do /dev/mouse mvi
mouse.do: mouse.c
cc mouse.c -o mouse.do
/dev/mouse:
/etc/mknod /dev/mouse p
mvi:
chmod +x mvi
S!H!A!R
fi # end of overwriting check
if test -f 'mouse.c'
then
echo shar: will not over-write existing file "'mouse.c'"
else
cat > 'mouse.c' << \S!H!A!R
/*
mvi - Mouse vi, an example of using the PC Mouse
This code will self-destroy when not used to make profit.
Author: Honzo Svasek
*/
#include <stdio.h>
#include <termio.h>
#include <fcntl.h>
int delta_x; /* movement in x direction (horizontal) */
int delta_y; /* movement in y direction (vertical) */
char but_1; /* button 1, 0 = up, 1 = down */
char but_2; /* button 2, 0 = up, 1 = down */
char but_3; /* button 3, 0 = up, 1 = down */
int fd; /* fd of mouse */
FILE *mouse, *o_mouse();
#define MOUSE_PORT "com1.d"
main(argc, argv)
int argc;
char *argv[];
{
char command[80];
int xnew=0, ynew=0, xold, yold;
int i, c;
if ((mouse = o_mouse(MOUSE_PORT)) == NULL) {
perror(MOUSE_PORT);
exit(-1);
}
for(;;) {
r_mouse(mouse);
if (but_1) {
fputc('\033', stdout);
}
if (but_2) {
fputc('.', stdout);
fflush(stdout);
fflush(mouse);
}
if (delta_y > 3) fputs("\033[B", stdout);
if (delta_y < -3) fputs("\033[A", stdout);
if (delta_x > 3) fputs("\033[C", stdout);
if (delta_x < -3) fputs("\033[D", stdout);
fflush(stdout);
}
}
/* r_mouse - read a string of mouse data */
r_mouse(mouse)
FILE *mouse;
{
char bn, x1, y1, x2, y2;
while (!(bn = fgetc(mouse) & 0x80);
x1 = fgetc(mouse);
y1 = fgetc(mouse);
x2 = fgetc(mouse);
y2 = fgetc(mouse);
delta_x = x1 > 128 ? x2 - x1 : x1 - x2;
delta_y = y1 < 128 ? y2 - y1 : y1 - y2;
but_1 = bn & 4 ? 0 : 1;
but_2 = bn & 2 ? 0 : 1;
but_3 = bn & 1 ? 0 : 1;
return 0;
}
FILE *o_mouse(port)
char *port;
{
char device[25];
struct termio tty;
FILE *fdopen();
strcpy(device, "/dev/");
strcat(device, port);
/* mouse-tty parameters */
tty.c_iflag = 0;
tty.c_cflag = B1200 | CS8 | CREAD;
tty.c_oflag = 0;
tty.c_lflag = 0;
tty.c_cc[4] = 5;
tty.c_cc[5] = 5;
if ((fd = open(device, O_RDONLY)) < 0) {
perror(device);
exit(-1);
}
ioctl(fd, TCSETA, &tty);
return fdopen(fd, "r");
}
S!H!A!R
fi # end of overwriting check
if test -f 'mvi'
then
echo shar: will not over-write existing file "'mvi'"
else
cat > 'mvi' << \S!H!A!R
# mvi - vi with mouse - you must be drunk!
if [ -p /dev/mouse -a -w /dev/mouse -a -r /dev/mouse ]
then
vi $* < /dev/mouse &
mouse.do > /dev/mouse &
cat -u > /dev/mouse
kill -9 $!
else
echo "mvi: you must have a named pipe /dev/mouse"
fi
S!H!A!R
chmod +x 'mvi'
fi # end of overwriting check
# End of shell archive
exit 0
--
I_I( _ UUCP: ..mcvax!honzo@4gl
I I ) Honzo Svasek @ 4GL Consultants b.v. FIDO: Honzo Svasek @ 500/333