login
Header Space

 
 

Re: PS/2 mouse

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
Date: Sunday, August 9, 1992 - 1:23 am

In article <JEM.92Aug8161453@silver-surfer.hut.fi> jem@niksula.hut.fi (Johan Myreen) writes:


You'll have to wait until tomorrow for the patches; I'll try to change
them to make the PS/2 mouse use the same major number as the bus
mouse.

By the way, the driver has been tested to work with X11. PS/2 mice
resemble serial mice a lot, but of course use a totally different
protocol. On the other hand, IBM defined the protocol, so all PS/2
mice use the same protocol. That doesn't help us very much, since the
protocol isn't supported by X386. But read on...

To make the mouse work with X11 I wrote the following program, which
translates the packets received from the PS/2 mouse into Microsoft
serial mouse packets, which it then writes to the master side of a
pseudo terminal. Then you tell X386 that you have a Microsoft serial
mouse on the slave side of the pty. This idea could be used to
fix other "jumpy" mice, if you know the protocols. The disadvantage is
that the pty has to be free. You can't just grab any pty (the first
free one, for instance), because it has to match the one in Xconfig.

Ok, here's the program. The driver will follow later.

/*
 * Microsoft serial mouse emulator for PS/2 mouse.
 *
 * This program converts the byte stream generated by a PS/2 mouse to
 * the corresponding Microsoft serial mouse byte stream.
 *
 * Give as an argument the master side of a free pseudo tty, for
 * instance:
 *
 * mconv /dev/ptyp1 &
 *
 * Specify the corresponding slave pty as the mouse device in Xconfig:
 *
 * Microsoft "/dev/ttyp1"
 *
 * This is an ugly hack; PS/2 mouse support should be added to X386.
 *
 * 
 * Johan Myreen
 * jem@cs.hut.fi
 */


#include <fcntl.h>
#include <stdio.h>
#include <signal.h>

#define MOUSE "/dev/psaux"

extern int errno;

static int pty, mouse;

void handler()
{
  fprintf(stderr, "\nMouse killed!\n");
  close(pty);
  close(mouse);
  exit(0);
}

unsigned char getbyte(void)
{
  static unsigned char buf[1024];
  static unsigned char *bp = buf, *ep = buf;
  int n;

  if (bp == ep) {
    bp = ep = buf;
    n = read(mouse, buf, 1024);
    if (n>0) {
      ep += n;
    }
  }
  return *bp++;
}


void track_mouse(void)
{
  unsigned char byte1, byte2, byte3, out[3], outbyte;

  while (1) {
    byte1 = getbyte();
    if (byte1 & 0xc0)
      continue;                         /* Resynchronize */
    byte2 = getbyte();
    byte3 = getbyte();
    byte3 = -byte3;
    outbyte = 0x40;
    outbyte |= ((byte2 >> 6)&0x03);
    outbyte |= ((byte3 >> 4)&0x0c);
    outbyte |= (byte1&0x01) << 5;       /* Left button */
    outbyte |= (byte1&0x02) << 3;       /* Right button */
    out[0] = outbyte;
    out[1] = (byte2)&0x3f;
    out[2] = (byte3)&0x3f;
    if (write(pty, out, 3) < 0)
      return;
  }
}


int main(int argc, char **argv)
{

  if (argc < 2) {
    fprintf(stderr, "Usage: %s /dev/ptypX, where X = 0..9 or a..f.\n", argv[0]);
    exit(1);
  }

  pty = open(argv[1], O_RDWR);

  if (pty < 0) {
    fprintf(stderr, "Error %d opening pty. Exiting.\n", errno);
    exit(1);
  }

  mouse = open(MOUSE, O_RDWR);

  if (mouse < 0) {
    fprintf(stderr, "Error %d opening mouse. Exiting.\n", errno);
    close(pty);
    exit(1);
  }

  signal(SIGTERM, handler);
  signal(SIGINT, handler);
  signal(SIGHUP, handler);

  track_mouse();

  fprintf(stderr, "Error %d reading or writing.\n", errno);
  close(pty);
  close(mouse);
}
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: PS/2 mouse, Johan Myreen, (Sun Aug 9, 1:23 am)
speck-geostationary