/* FirstMouse+ Diagnositics
 *
 * This program polls the mouse port and records
 * three byte long events.  The events are then
 * interpreted according to the signals that are
 * put out by the Retail version of the Logitech
 * FirstMouse+
 *
 * Events are dumped in binary along with the
 * interpretation
 *
 * Written by A. Norman (norman@physics.wm.edu)
 * http://www.physics.wm.edu/~norman/Mouse_Diag/
 *
 * This source is distributed under GNU General
 * Public License.  See file "COPYING" for details
 *
 * $Id: mouse_diag.c,v 1.1.1.1 1999/08/21 04:25:42 norman Exp $
 * $Log: mouse_diag.c,v $
 * Revision 1.1.1.1  1999/08/21 04:25:42  norman
 * Logitech Mouse Diagnostics
 *
 * Revision 1.2  1999/07/10 13:48:04  norman
 * Code stabilized.  Added MAX_EVENTS macros to
 * control event processing.  Removed single byte,
 * and word processing in favor of padded long words.
 *
 */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "binary_display.h"

#define MAX_EVENTS 0x000000FF

/* This is a 32bit data structure allowing access 
   to the various parts of the data words */
union port_data
{
  unsigned int   port_long_word;   /* 1x 32bits */
  unsigned short port_word[2];     /* 2x 16bits */
  unsigned char  port_byte[4];     /* 4x 8bits  */
};

void print_event_byte_type(unsigned int mouse_long_word)
{
  switch(mouse_long_word)
    {
    case 0x00000008 : printf("Logitech Mouse Button Release    \n"); break ;
    case 0x00000009 : printf("Logitech Mouse Button 1 DOWN     \n"); break ;
    case 0x0000000a : printf("Logitech Mouse Button 2 DOWN     \n"); break ;
    case 0x0000000c : printf("Logitech Mouse Button 3 DOWN     \n"); break ;
    case 0x000fdec8 : printf("Logitech Mouse Button Wheel Up   \n"); break ;
    case 0x0001d6c8 : printf("Logitech Mouse Button Wheel Down \n"); break ;
    case 0x00000108 : printf("Logitech Mouse Right             \n"); break ;
    case 0x0000ff18 : printf("Logitech Mouse Left              \n"); break ;
    case 0x00010008 : printf("Logitech Mouse Up                \n"); break ;
    case 0x00ff0028 : printf("Logitech Mouse Down              \n"); break ;
    default:          printf("Unknown Event           \n"); break ;
    }
}

int read_port_raw(int file_descriptor)
{
  union port_data mouse_dat;
  unsigned int max_events = MAX_EVENTS;                         /* Maxium of 255 events     */ 
  unsigned int i=0,j=0;                                         /* Loop counter             */

  mouse_dat.port_long_word = 0;                                 /* Zero out the long word   */
  for(i=0;i!=max_events;)
    {
      i++;                                                      /* Inc the event counter    */
      read(file_descriptor,&mouse_dat.port_byte[0],1);          /* Read Byte 1 of data      */
      read(file_descriptor,&mouse_dat.port_byte[1],1);          /* Read Byte 2 of data      */
      read(file_descriptor,&mouse_dat.port_byte[2],1);          /* Read Byte 3 of data      */
      if(mouse_dat.port_long_word)                              /* If the event is non-zero */
	{
	  printf("Event %d -> ",i);                             /* Print the event num      */
	  display_char(mouse_dat.port_byte[2]);                 /* Display bytes 1          */
	  display_char(mouse_dat.port_byte[1]);                 /* Display bytes 2          */
	  display_char(mouse_dat.port_byte[0]);                 /* Display bytes 3          */
	  print_event_byte_type(mouse_dat.port_long_word);      /* Identify the code        */
	}
      mouse_dat.port_long_word=0;                               /* Re-zero the long word    */
    }
  return 1;
}


int main(int argc,char** argv)
{
  int file_descriptor;
  
  /* Open a device to read */
  if(argc > 1)
    {
      printf("Using device: %s\n",argv[1]);
      file_descriptor = open(argv[1],O_RDWR,O_NOCTTY|O_SYNC);
    }
  else
    {
      printf("Using device: /dev/psaux\n");
      file_descriptor = open("/dev/psaux",O_RDWR,O_NOCTTY|O_SYNC);
    }

  read_port_raw(file_descriptor); /* Read the raw port data and display results */

  return 1;
}
  
