[comp.os.minix] Atari ST mouse driver

7103_300@uwovax.uwo.ca (Eric Smith) (02/14/89)

Here's a mouse driver for Minix/ST. It's fairly primitive, but does
the job. I've included a very simple drawing program as an example
of how to read the mouse. I forgot to mention this in the README
file, but the sketch program needs my previously posted /dev/screen
driver.

Bug reports, etc. may be sent to me at the address below. Please
put "ATTN: Eric Smith" or something similar on your message to make
sure I get it.
---
Eric R. Smith                     email:
Dept. of Mathematics            7103_300@uwovax.uwo.ca
University of Western Ontario   7103_300@uwovax.bitnet
London, Ont. Canada N6A 5B7     (a shared mailbox: put my name on
ph: (519) 661-3638              the message, please!)
------------------------ 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:  README h.cdiff kernel.cdiff sttools.cdiff sketch.c
# Wrapped by root@Eric's Minix/ST on Mon Feb 13 17:54:06 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1620 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X   Here's a mouse driver for the Atari ST. To install it, copy the
Xfiles named xxx.cdiff to the appropriate minix source directory (e.g.
Xkernel.cdiff goes wherever you put the kernel source), run them
Xthrough patch, and recompile. These diffs are with respect to my kernel,
Xwhich is basically the minix distribution with the /dev/screen driver
Xadded. If you've added device drivers (e.g. for the BMS clock or
XRS232) you may have to apply some of the patches by hand; files likely
Xto have problems are {kernel, fs}/table.c and h/com.h. After you've
Xrebuilt minix, copy the file kernel/mouse.h to /usr/include/minix,
Xand install in /dev for the mouse device; on my system, I did a
X   mknod /dev/mouse c 7 0; chmod 444 /dev/mouse.
X
XHow it works
X------------
X   Reads from the mouse device always succeed, and return up
Xto 6 bytes; the first two give the current button status, the next
Xtwo give the change in the X coordinate since the last read, and
Xthe last two give the change in the Y coordinate. There is a
Xstructure defined in <minix/mouse.h> that can conveniently be
Xused for this:
X
X   struct mouse_buf mb;
X   read(fd, &mb, sizeof(mb));
X
XNote that the first read from the mouse always gives
Xdelta X == delta Y == 0.
X
XIncluded in the distribution is a sample program, sketch.c, that shows
Xthe use of the mouse driver.
X
XBUGS:
X----
X   The driver uses the internal coordinate counter for the mouse kept
Xby the keyboard. This gives a 32000x32000 field for the mouse; if you keep
Xmoving the mouse in the same direction long enough, you could bump into the
Xedge (of course, you run out of screen a long time before then!).
END_OF_FILE
if test 1620 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'h.cdiff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'h.cdiff'\"
else
echo shar: Extracting \"'h.cdiff'\" \(2170 characters\)
sed "s/^X//" >'h.cdiff' <<'END_OF_FILE'
X*** /tmp/,RCSt1000041	Sun Feb 12 12:21:46 1989
X--- com.h	Sun Feb 12 11:48:49 1989
X***************
X*** 54,59 ****
X--- 54,62 ----
X  #	define TTY_SETPGRP 6	/* fcn code for setpgrp */
X  #	define SUSPEND	-998	/* used in interrupts when tty has no data */
X  
X+ #define MOUSE		  -9	/* for the mouse driver */
X+ #	define MOUSE_INT   1	/* fcn code for mouse input interrupt */
X+ 
X  /* Names of message fields for messages to CLOCK task. */
X  #define DELTA_TICKS    m6_l1	/* alarm interval in clock ticks */
X  #define FUNC_TO_CALL   m6_f1	/* pointer to function to call */
X***************
X*** 74,79 ****
X--- 77,87 ----
X  #define TTY_SPEK       m2_l1	/* message parameter: ioctl speed, erasing */
X  #define TTY_FLAGS      m2_l2	/* message parameter: ioctl tty mode */
X  #define TTY_PGRP       m2_i3    /* message parameter: process group */
X+ 
X+ /* Names of message fields for messages to the MOUSE task */
X+ #define MOUSE_BUT      m2_i1	/* mouse button states */
X+ #define MOUSE_X	       m2_i2	/* mouse X coordinate */
X+ #define MOUSE_Y	       m2_i3	/* mouse Y coordinate */
X  
X  /* Names of messages fields used in reply messages from tasks. */
X  #define REP_PROC_NR    m2_i1	/* # of proc on whose behalf I/O was done */
X*** /tmp/,RCSt1000041	Sun Feb 12 12:21:58 1989
X--- const.h	Thu Feb  9 18:01:07 1989
X***************
X*** 22,28 ****
X  #define MAJOR	           8	/* major device = (dev>>MAJOR) & 0377 */
X  #define MINOR	           0	/* minor device = (dev>>MINOR) & 0377 */
X  
X! #define NR_TASKS           8	/* number of tasks in the transfer vector */
X  #define NR_PROCS          16	/* number of slots in proc table */
X  #define NR_SEGS            3	/* # segments per process */
X  #define T                  0	/* proc[i].mem_map[T] is for text */
X--- 22,28 ----
X  #define MAJOR	           8	/* major device = (dev>>MAJOR) & 0377 */
X  #define MINOR	           0	/* minor device = (dev>>MINOR) & 0377 */
X  
X! #define NR_TASKS           9	/* number of tasks in the transfer vector */
X  #define NR_PROCS          16	/* number of slots in proc table */
X  #define NR_SEGS            3	/* # segments per process */
X  #define T                  0	/* proc[i].mem_map[T] is for text */
END_OF_FILE
if test 2170 -ne `wc -c <'h.cdiff'`; then
    echo shar: \"'h.cdiff'\" unpacked with wrong size!
fi
# end of 'h.cdiff'
fi
if test -f 'kernel.cdiff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kernel.cdiff'\"
else
echo shar: Extracting \"'kernel.cdiff'\" \(11310 characters\)
sed "s/^X//" >'kernel.cdiff' <<'END_OF_FILE'
X*** /tmp/,RCSt1000064	Sun Feb 12 12:25:39 1989
X--- Makefile	Thu Feb  9 20:39:18 1989
X***************
X*** 8,19 ****
X  OBJ	= stmpx.o stmain.o proc.o system.o stshadow.o \
X  	  tty.o clock.o memory.o stdma.o stfloppy.o stwini.o \
X  	  stcon.o stkbd.o stvdu.o stfnt.o stprint.o \
X! 	  table.o stdmp.o
X  HDR	= ../h/callnr.h ../h/com.h ../h/const.h ../h/error.h \
X  	  ../h/sgtty.h ../h/signal.h ../h/type.h \
X  	  const.h glo.h proc.h tty.h type.h \
X  	  stacia.h staddr.h stdma.h stfdc.h sthdc.h stmfp.h \
X! 	  stram.h stsound.h stvideo.h
X  ALL	= kernel.mix
X  
X  all:	$(ALL)
X--- 8,19 ----
X  OBJ	= stmpx.o stmain.o proc.o system.o stshadow.o \
X  	  tty.o clock.o memory.o stdma.o stfloppy.o stwini.o \
X  	  stcon.o stkbd.o stvdu.o stfnt.o stprint.o \
X! 	  stmouse.o table.o stdmp.o
X  HDR	= ../h/callnr.h ../h/com.h ../h/const.h ../h/error.h \
X  	  ../h/sgtty.h ../h/signal.h ../h/type.h \
X  	  const.h glo.h proc.h tty.h type.h \
X  	  stacia.h staddr.h stdma.h stfdc.h sthdc.h stmfp.h \
X! 	  stram.h stsound.h stvideo.h mouse.h
X  ALL	= kernel.mix
X  
X  all:	$(ALL)
X*** /tmp/,RCSt1000064	Sun Feb 12 12:25:50 1989
X--- stdmp.c	Fri Feb 10 10:51:29 1989
X***************
X*** 121,127 ****
X  }
X  
X  
X! char *nayme[]= {"PRINTR", "TTY   ", "WINCHE", "FLOPPY", "RAMDSK", "CLOCK ", 
X  		"SYS   ", "HARDWR", "MM    ", "FS    ", "INIT  "};
X  prname(i)
X  int i;
X--- 121,128 ----
X  }
X  
X  
X! char *nayme[]= {"MOUSE ", "PRINTR", "TTY   ", "WINCHE",
X! 		"FLOPPY", "RAMDSK", "CLOCK ", 
X  		"SYS   ", "HARDWR", "MM    ", "FS    ", "INIT  "};
X  prname(i)
X  int i;
X*** /tmp/,RCSt1000064	Sun Feb 12 12:26:03 1989
X--- stkbd.c	Sun Feb 12 11:58:29 1989
X***************
X*** 9,17 ****
X  
X  #include "staddr.h"
X  #include "stacia.h"
X! 
X  #include "tty.h"
X  
X  /*
X   * Translation from keyboard codes into internal (ASCII like) codes
X   * These tables represents a US keyboard, so MINIX.IMG as found on
X--- 9,18 ----
X  
X  #include "staddr.h"
X  #include "stacia.h"
X! #include "mouse.h"
X  #include "tty.h"
X  
X+ #define MAX_COORD 32000
X  /*
X   * Translation from keyboard codes into internal (ASCII like) codes
X   * These tables represents a US keyboard, so MINIX.IMG as found on
X***************
X*** 105,110 ****
X--- 106,116 ----
X  PRIVATE message	kbdmes;		/* message used for console input chars */
X  PRIVATE int	repeatkey;	/* character to repeat */
X  PRIVATE int	repeattic;	/* time to next repeat */
X+ PRIVATE int	mousekeys = 0;	/* # characters left in mouse packet */
X+ 
X+ PRIVATE int	leftmouse, rightmouse,
X+ 		mousex = MAX_COORD/2,
X+ 		mousey = MAX_COORD/2;		/* used by mouse device */
X  
X  /*===========================================================================*
X   *				kbdint					     *
X***************
X*** 112,124 ****
X  PUBLIC kbdint()
X  {
X    register code, make, k;
X  
X    k = kbdbuf[0];
X    /*
X     * There may be multiple keys available. Read them all.
X     */
X!   while (KBD->ac_cs & A_IRQ) {
X! 	code = KBD->ac_da;
X  /*	printf("kbd: got %x\n", code & 0xFF); */
X  	/*
X  	 * The ST's keyboard interrupts twice per key,
X--- 118,131 ----
X  PUBLIC kbdint()
X  {
X    register code, make, k;
X+   register char stat;
X  
X    k = kbdbuf[0];
X    /*
X     * There may be multiple keys available. Read them all.
X     */
X!   while (((stat = KBD->ac_cs) & A_IRQ) && (stat & A_RXRDY)) {
X!      code = ((int) KBD->ac_da) & 0xFF;
X  /*	printf("kbd: got %x\n", code & 0xFF); */
X  	/*
X  	 * The ST's keyboard interrupts twice per key,
X***************
X*** 126,131 ****
X--- 133,165 ----
X  	 * Filter out the latter, ignoring all but
X  	 * the shift-type keys.
X           */
X+ 
X+      if (mousekeys > 0) {	/* this is part of a mouse packet */
X+ 	switch(mousekeys--) {
X+ 	   case 5:		/* mouse button state */
X+ 		break;		/* ignore it; we already know about it */
X+ 	   case 4:
X+ 	   case 3:		/* mouse X position bytes */
X+ 		mousex = (mousex << 8) + code;
X+ 		break;
X+ 	   case 2:
X+ 	   case 1:		/* mouse Y position bytes */
X+ 		mousey = (mousey << 8) + code;
X+ 		break;
X+ 	}
X+ 	if (mousekeys == 0) {	/* mouse packet finished */
X+ 		kbdmes.m_type = MOUSE_INT;
X+ 		kbdmes.MOUSE_BUT = (leftmouse << 1) | rightmouse;
X+ 		kbdmes.MOUSE_X = mousex;
X+ 		kbdmes.MOUSE_Y = mousey;
X+ 		interrupt(MOUSE, &kbdmes);
X+ 	}
X+      }
X+      else if ( code == 0xF7 ) {
X+ 		mousekeys = 5;	/* expect five more chars for mouse */
X+ 		mousex = mousey = 0;
X+      }
X+      else {
X  	make = code & 0x80 ? 0 : 1;	/* 1=depressed, 0=released */
X  	code &= 0x7F;
X  	switch (code) {
X***************
X*** 139,144 ****
X--- 173,182 ----
X  		alt = make; continue;
X  	case 0x3A:	/* caps lock */
X  		if (make) capslock ^= 1; continue;
X+ 	case 0x74:	/* left mouse button */
X+ 		leftmouse = make; continue;
X+ 	case 0x75:	/* right mouse button */
X+ 		rightmouse = make; continue;
X  	}
X  	if (make == 0) {
X  		repeattic = 0;
X***************
X*** 147,153 ****
X--- 185,194 ----
X  	repeatkey = code;
X  	repeattic = 24;	/* delay: 24 * 16 msec == 0.4 sec */
X  	kbdkey(code);
X+      }
X    }
X+   if (stat & A_OE)		/* Overrun error? */
X+ 	code = KBD->ac_da;	/* if so, clear it */
X    if (kbdbuf[0] != k) {
X  	/* Build and send the interrupt message. */
X  	kbdmes.m_type = TTY_CHAR_INT;
X***************
X*** 366,375 ****
X   *===========================================================================*/
X  PUBLIC kbdinit()
X  {
X    KBD->ac_cs = KBD_INIT | A_RXINT;
X  	/* divide by 16, 8 data, 1 stop, no parity, enable interrupts */
X!   KBD->ac_da = 0x12;
X! 	/* mouse off */
X    kbdbuf[1] = MAX_OVERRUN;	/* set up limit on keyboard buffering */
X  }
X  #endif ATARI_ST
X--- 407,443 ----
X   *===========================================================================*/
X  PUBLIC kbdinit()
X  {
X+   int maxx, maxy;
X+ 
X+   maxx = maxy = MAX_COORD;
X    KBD->ac_cs = KBD_INIT | A_RXINT;
X  	/* divide by 16, 8 data, 1 stop, no parity, enable interrupts */
X! 
X!   kbdsend(0x09);		/* mouse in absolute mode */
X!   kbdsend(maxx/256); kbdsend(maxx & 0xFF);
X! 	 /* maximum X coordinate */
X!   kbdsend(maxy / 256); kbdsend(maxy & 0xFF);
X! 	 /* maximum Y coordinate */
X!   kbdsend(0x0E);		/* set current coordinates */
X!   kbdsend(0);			/* filler */
X!   kbdsend(mousex/256); kbdsend(mousex & 0xFF);
X! 	 /* current X */
X!   kbdsend(mousey/256); kbdsend(mousey & 0xFF);
X! 	 /* current Y */
X! 
X!   kbdsend(0x07);		/* set mouse button handling */
X!   kbdsend(0x04);		/* treat buttons like keys */
X    kbdbuf[1] = MAX_OVERRUN;	/* set up limit on keyboard buffering */
X+ }
X+ 
X+ /*===========================================================================*
X+  *				kbdsend				     	     *
X+  *===========================================================================*/
X+ PUBLIC kbdsend(c)
X+ int c;
X+ {
X+   /* send a character to the keyboard chip */
X+   while(!(KBD->ac_cs & A_TXRDY)) ;	/* wait until kbd is ready */
X+   KBD->ac_da = c;			/* send the character */
X  }
X  #endif ATARI_ST
X*** /tmp/,RCSt1000064	Sun Feb 12 12:26:20 1989
X--- table.c	Fri Feb 10 10:51:30 1989
X***************
X*** 33,39 ****
X  #include "proc.h"
X  
X  extern int sys_task(), clock_task(), mem_task(), floppy_task(),
X!            winchester_task(), tty_task(), printer_task();
X  
X  /* The startup routine of each task is given below, from -NR_TASKS upwards.
X   * The order of the names here MUST agree with the numerical values assigned to
X--- 33,39 ----
X  #include "proc.h"
X  
X  extern int sys_task(), clock_task(), mem_task(), floppy_task(),
X!            winchester_task(), tty_task(), printer_task(), mouse_task();
X  
X  /* The startup routine of each task is given below, from -NR_TASKS upwards.
X   * The order of the names here MUST agree with the numerical values assigned to
X***************
X*** 40,45 ****
X--- 40,46 ----
X   * the tasks in ../h/com.h.
X   */
X  int (*task[NR_TASKS+INIT_PROC_NR+1])() = {
X+  mouse_task,
X   printer_task, tty_task, winchester_task, floppy_task, mem_task,
X   clock_task, sys_task, 0, 0, 0, 0
X  };
X*** empty	Sun Feb 12 12:30:40 1989
X--- mouse.h	Sun Feb 12 12:31:17 1989
X***************
X*** 0 ****
X--- 1,11 ----
X+ /* header file for mouse access */
X+ 
X+ struct mouse_buf {
X+ 	short m_buttons;	/* button states */
X+ 	short m_dx;	/* change in x since last read */
X+ 	short m_dy;	/* change in y since last read */
X+ };
X+ 
X+ #define M_LEFT_BUTTON	0x02
X+ #define M_RIGHT_BUTTON	0x01
X+ #define M_MID_BUTTON	0x00	/* there is none! */
X*** empty	Sun Feb 12 12:30:40 1989
X--- stmouse.c	Sun Feb 12 12:10:30 1989
X***************
X*** 0 ****
X--- 1,107 ----
X+ /* This file contains the drivers for the mouse device,
X+  *     /dev/mouse.
X+  *
X+  * It accepts only one message, for reading.
X+  *
X+  *    m_type      DEVICE    PROC_NR     COUNT    POSITION  ADRRESS
X+  * ----------------------------------------------------------------
X+  * |  DISK_READ | device  | proc nr |  bytes  |  offset | buf ptr |
X+  * ----------------------------------------------------------------
X+  *
X+  * The file contains one entry point:
X+  *
X+  *   mouse_task:	main entry when system is brought up
X+  *
X+  */
X+ 
X+ #include "../h/const.h"
X+ #include "../h/type.h"
X+ #include "../h/callnr.h"
X+ #include "../h/com.h"
X+ #include "../h/error.h"
X+ #include "const.h"
X+ #include "type.h"
X+ #include "proc.h"
X+ #include "mouse.h"
X+ 
X+ PRIVATE message mess;		/* message buffer */
X+ PRIVATE struct mouse_buf mb;
X+ PRIVATE int changed;		/* has the mouse moved?? */
X+ 
X+ PRIVATE int oldx, oldy;		/* previous values for mouse coord.'s */
X+ 
X+ /*===========================================================================*
X+  *				mouse_task				     * 
X+  *===========================================================================*/
X+ 
X+ PUBLIC mouse_task()
X+ {
X+ /* Main program of the disk driver task. */
X+ 
X+   int r, caller, proc_nr;
X+ 
X+   /* Initialize this task. */
X+   mb.m_dx = mb.m_dy = mb.m_buttons = 0;
X+ 
X+   /* Here is the main loop of the mouse task.  It waits for a message, carries
X+    * it out, and sends a reply.
X+    */
X+   while (TRUE) {
X+ 	/* First wait for a request to read or write. */
X+ 	receive(ANY, &mess);
X+ 	caller = mess.m_source;
X+ 	proc_nr = mess.PROC_NR;
X+ 
X+ 	/* Now carry out the work.  It depends on the opcode. */
X+ 	switch(mess.m_type) {
X+ 	    case DISK_READ:
X+ 		r = do_read(&mess);
X+ 		break;
X+ 	    default:
X+ 		r = EINVAL;
X+ 		break;
X+ 	}
X+ 
X+ 	/* Finally, prepare and send the reply message. */
X+ 	mess.m_type = TASK_REPLY;
X+ 	mess.REP_PROC_NR = proc_nr;
X+ 	mess.REP_STATUS = r;
X+ 	send(caller, &mess);
X+    }
X+ }
X+ 
X+ /*===========================================================================*
X+  *				do_read					     * 
X+  *===========================================================================*/
X+ 
X+ PRIVATE do_read(m_ptr)
X+ register message *m_ptr;
X+ {
X+ 	unsigned count;
X+ 	phys_bytes user_phys;
X+ 	struct proc *rp;
X+ 	extern phys_bytes umap();
X+ 	static int mousex, mousey;
X+ 	static message msg;
X+ 
X+ 	oldx = mousex; oldy = mousey;
X+ 	kbdsend(0x0d);		/* ask kbd chip for mouse position */
X+ 	receive(HARDWARE, &msg);
X+ 	mousex = msg.MOUSE_X;
X+ 	mousey = msg.MOUSE_Y;
X+ 	if (m_ptr->POSITION == 0) {
X+ 		mb.m_dx = mb.m_dy = 0;
X+ 	}
X+ 	else {
X+ 		mb.m_dx = mousex - oldx;
X+ 		mb.m_dy = mousey - oldy;
X+ 	}
X+ 	mb.m_buttons = msg.MOUSE_BUT;
X+ 
X+ 	count = MIN(count, sizeof(mb));
X+ 	rp = proc_addr(m_ptr->PROC_NR);
X+ 	user_phys = umap(rp, D, (vir_bytes) m_ptr->ADDRESS, (vir_bytes) count);
X+ 	if (user_phys == 0) return(E_BAD_ADDR);
X+ 	phys_copy( (phys_bytes) &mb, user_phys, (long) count);
X+ 	return count;
X+ }
END_OF_FILE
if test 11310 -ne `wc -c <'kernel.cdiff'`; then
    echo shar: \"'kernel.cdiff'\" unpacked with wrong size!
fi
# end of 'kernel.cdiff'
fi
if test -f 'sttools.cdiff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sttools.cdiff'\"
else
echo shar: Extracting \"'sttools.cdiff'\" \(258 characters\)
sed "s/^X//" >'sttools.cdiff' <<'END_OF_FILE'
X*** Makedev.B	Wed Feb  8 23:02:58 1989
X--- Makedev	Sun Feb 12 12:39:49 1989
X***************
X*** 30,32 ****
X--- 30,33 ----
X  mknod tty0 c 4 0; chmod 666 tty0
X  mknod tty c 5 0; chmod 666 tty
X  mknod lp c 6 0; chmod 222 lp
X+ mknod mouse c 7 0; chmod 444 mouse
END_OF_FILE
if test 258 -ne `wc -c <'sttools.cdiff'`; then
    echo shar: \"'sttools.cdiff'\" unpacked with wrong size!
fi
# end of 'sttools.cdiff'
fi
if test -f 'sketch.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sketch.c'\"
else
echo shar: Extracting \"'sketch.c'\" \(2379 characters\)
sed "s/^X//" >'sketch.c' <<'END_OF_FILE'
X/* a very primitive "sketching" program to test the mouse driver */
X/*    --ERS 							 */
X
X#include <stdio.h>
X#include <minix/screen.h>
X#include <minix/mouse.h>
X#include <sgtty.h>
X
Xint width, height, depth;	/* screen parameters */
Xint mousex, mousey;		/* mouse position */
Xint scrnfd, mousefd;		/* file handles for mouse and screen */
Xint linesiz;			/* words in a screen line */
Xint drawing;			/* if nonzero, leave plotted points on screen */
X
Xshort *screen;			/* screen address */
Xstruct scr_param sp;		/* for ioctl call to get screen parameters */
Xstruct scr_palette sc;		/* for screen colors (not used right now */
X
Xmain()
X{
X	register int oldx, oldy;
X
X	scrnfd = open("/dev/screen", 0);
X	if (scrnfd < 0) {
X		perror("/dev/screen");
X		exit(1);
X	}
X	mousefd = open("/dev/mouse", 0);
X	if (mousefd < 0) {
X		perror("/dev/mouse");
X		exit(1);
X	}
X
X/* get the screen parameters */
X	ioctl(scrnfd, SCRGETPARAM, &sp);
X	ioctl(scrnfd, SCRGETCOLOR, &sc);
X	screen = (short *) sp.scr_base;
X
X	clrscreen();
X	width = sp.scr_width;
X	height = sp.scr_height;
X	depth = sp.scr_depth;
X	linesiz = (depth * width) / 16;
X	mousex = mousey = 0;
X	for (;;) {
X		plot(mousex, mousey);
X		oldx = mousex; oldy = mousey;
X		getmouse();	/* get new mouse position */
X		if (!drawing)
X			plot(oldx, oldy);
X	}
X}
X
X/* procedure to clear the screen */
Xclrscreen()
X{
X	register short *addr, i;
X
X	addr = screen;
X	for (i = 0; i < 16000; i++)
X		*addr++ = 0;
X}
X
X/* procedure to plot a point at (x,y) on screen */
X
Xplot(x, y)
Xregister int x, y;
X{
X	register short *addr, word;
X	int bit;
X
X	if (x < 0 || y < 0 || x >= width || y >= height)
X		return;
X	addr = screen + (y * linesiz);
X	bit = x % 16;
X	addr += (depth * (x/16));
X	word = *addr;
X	if (drawing)
X		word |= (0x8000 >> bit);
X	else
X		word ^= (0x8000 >> bit);
X	*addr = word;
X}
X
X/* get new mouse coordinates and button states */
X
Xgetmouse()
X{
X	static struct mouse_buf mb;
X	register int but;
X
X	read(mousefd, &mb, sizeof(mb)); 
X
X	but = mb.m_buttons;
X	drawing = (but & M_LEFT_BUTTON) ? 1 : 0;
X	if (but & M_RIGHT_BUTTON) {
X		if (drawing) 		/* both buttons down means exit */
X			exit(0);
X		else {
X			clrscreen();
X	/* kludge to trick main loop into not redrawing mouse cursor */
X			drawing = 1;
X		}
X	}
X
X	mousex += mb.m_dx;
X	mousey += mb.m_dy;
X	if (mousex < 0) mousex = 0;
X	if (mousex >= width) mousex = width - 1;
X	if (mousey < 0) mousey = 0;
X	if (mousey >= height) mousey = height - 1;
X
X}
END_OF_FILE
if test 2379 -ne `wc -c <'sketch.c'`; then
    echo shar: \"'sketch.c'\" unpacked with wrong size!
fi
# end of 'sketch.c'
fi
echo shar: End of shell archive.
exit 0

n62@nikhefh.hep.nl (Klamer Schutte) (02/27/89)

In the posting of Eric was i think a patch missing to fs/table.c making the 
mouse driver known to fs. Here  is my fix; it maked the driver work with the
supplied program sketch.

Klamer.
(signature at end )
---------------------------------------------------------------------------
*** /usr/fs/table.c~	Thu Feb 24 12:00:55 1989
--- table.c	Thu Feb 24 12:06:37 1989
***************
*** 124,130 ****
      no_call,   rw_dev,      no_call,    WINCHESTER,  /* 3 = /dev/hd0  */
      tty_open,  rw_dev,      no_call,    TTY,         /* 4 = /dev/tty0 */
      no_call,   rw_dev2,     no_call,    TTY,         /* 5 = /dev/tty  */
!     no_call,   rw_dev,      no_call,    PRINTER      /* 6 = /dev/lp   */
  };
  
  int max_major = sizeof(dmap)/sizeof(struct dmap);
--- 124,131 ----
      no_call,   rw_dev,      no_call,    WINCHESTER,  /* 3 = /dev/hd0  */
      tty_open,  rw_dev,      no_call,    TTY,         /* 4 = /dev/tty0 */
      no_call,   rw_dev2,     no_call,    TTY,         /* 5 = /dev/tty  */
!     no_call,   rw_dev,      no_call,    PRINTER,     /* 6 = /dev/lp   */
!     no_call,   rw_dev,	    no_call,	MOUSE	     /* 7 = /dev/mouse */
  };
  
  int max_major = sizeof(dmap)/sizeof(struct dmap);
-- 
________________________________________________________________________________
Klamer Schutte			mcvax!nikhefh!n62	      n62@nikhefh.hep.nl

ralph@cc.brunel.ac.uk (Ralph Mitchell) (02/27/89)

In article <1611@uwovax.uwo.ca> 7103_300@uwovax.uwo.ca (Eric Smith) writes:
>Here's a mouse driver for Minix/ST. It's fairly primitive, but does
>the job. I've included a very simple drawing program as an example
>of how to read the mouse. I forgot to mention this in the README
>file, but the sketch program needs my previously posted /dev/screen
>driver.

The screen driver works like a charm, but I found a slight problem
with the mouse driver.  I got:

  fs: filesystem panic: bad major device 7

It turns out that an entry needs to be made in the table of drivers in
fs/table.c.  The last few lines should read like this:

        tty_open,  rw_dev,      no_call,    TTY,         /* 4 = /dev/tty0 */
        no_call,   rw_dev2,     no_call,    TTY,         /* 5 = /dev/tty  */
        no_call,   rw_dev,      no_call,    PRINTER,     /* 6 = /dev/lp   */
->      no_call,   rw_dev,      no_call,    MOUSE        /* 7 = /dev/mouse */
    };

    int max_major = sizeof(dmap)/sizeof(struct dmap);


I'm not 100% sure this is correct, but it works for me :-)  Perhaps Eric
could confirm this ??  I guess he may have just overlooked this diff...

Recompiling with this fix makes the 'sketch' program work OK.

Ralph Mitchell
-- 
 From:  Ralph Mitchell at Brunel University, Uxbridge, UB8, 3PH, UK
 JANET: ralph@uk.ac.brunel.cc	  ARPA:  ralph%cc.brunel.ac.uk@cwi.nl
 UUCP:  ...ukc!cc.brunel!ralph   PHONE: +44 895 74000 x2561
 "There's so many different worlds, so many different Suns" -- Dire Straits

7103_300@uwovax.uwo.ca (Eric Smith) (03/03/89)

In article <646@Terra.cc.brunel.ac.uk>, ralph@cc.brunel.ac.uk (Ralph Mitchell) writes:
> The screen driver works like a charm, but I found a slight problem
> with the mouse driver.  I got:
> 
>   fs: filesystem panic: bad major device 7
> 
> It turns out that an entry needs to be made in the table of drivers in
> fs/table.c.  The last few lines should read like this:
> 
>         tty_open,  rw_dev,      no_call,    TTY,         /* 4 = /dev/tty0 */
>         no_call,   rw_dev2,     no_call,    TTY,         /* 5 = /dev/tty  */
>         no_call,   rw_dev,      no_call,    PRINTER,     /* 6 = /dev/lp   */
> ->      no_call,   rw_dev,      no_call,    MOUSE        /* 7 = /dev/mouse */
>     };
> 
>     int max_major = sizeof(dmap)/sizeof(struct dmap);
> 
> 
> I'm not 100% sure this is correct, but it works for me :-)  Perhaps Eric
> could confirm this ??  I guess he may have just overlooked this diff...
> 
> Recompiling with this fix makes the 'sketch' program work OK.
> 
> Ralph Mitchell
> -- 
>  From:  Ralph Mitchell at Brunel University, Uxbridge, UB8, 3PH, UK
>  JANET: ralph@uk.ac.brunel.cc	  ARPA:  ralph%cc.brunel.ac.uk@cwi.nl
>  UUCP:  ...ukc!cc.brunel!ralph   PHONE: +44 895 74000 x2561

Oops. You're absolutely right; I must have forgotten the patches (well, patch;
the one you just outlined) for fs. Sorry. Your suggested patch is exactly
what's needed. Thanks for pointing this out.

There's also a small bug in stmouse.c; around line 100 there's a line that
reads:

count = MIN(count, sizeof(mb));

It should read:

count = MIN(m_ptr->COUNT, sizeof(mb));

(the variable "count" isn't initialized at this point). This fix, and a few
more, are incorporated into my patch to the rs232 kernel (see next posting).
--
Eric R. Smith                      email:
Dept. of Mathematics               7103_300@uwovax.uwo.ca
University of Western Ontario      7103_300@uwovax.bitnet
London, Ont. Canada N6A 5B7    (a shared mailbox: put my name on
ph: (519) 661-3638              the Subj: line, please!)