283 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			283 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include <errno.h>
							 | 
						||
| 
								 | 
							
								#include <fcntl.h>
							 | 
						||
| 
								 | 
							
								#include <unistd.h>
							 | 
						||
| 
								 | 
							
								#include <sys/time.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								unsigned char* inbuffer;
							 | 
						||
| 
								 | 
							
								unsigned char* outbuffer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// wait for up to 0.1seconds for an acknowledgement
							 | 
						||
| 
								 | 
							
								int getack(int fd) {
							 | 
						||
| 
								 | 
							
								  fd_set set;
							 | 
						||
| 
								 | 
							
								  timeval timeout;
							 | 
						||
| 
								 | 
							
								  FD_ZERO(&set);
							 | 
						||
| 
								 | 
							
								  FD_SET(fd,&set);
							 | 
						||
| 
								 | 
							
								  timeout.tv_sec=0;
							 | 
						||
| 
								 | 
							
								  timeout.tv_usec=100000;
							 | 
						||
| 
								 | 
							
								  if (select(FD_SETSIZE,&set,NULL,NULL,&timeout)) {
							 | 
						||
| 
								 | 
							
								    int b=read(fd,inbuffer,1);
							 | 
						||
| 
								 | 
							
								    if(b==1) {
							 | 
						||
| 
								 | 
							
								      if(inbuffer[0]==0xfa) {
							 | 
						||
| 
								 | 
							
								        //printf("<< Acknowledged\r\n");
							 | 
						||
| 
								 | 
							
								        return 1;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      else if (inbuffer[0]=0xfe)
							 | 
						||
| 
								 | 
							
								        printf("<- PS/2: Error\r\n");
							 | 
						||
| 
								 | 
							
								      else	
							 | 
						||
| 
								 | 
							
								        printf("<- Not an acknowledgement:%02x\r\n",inbuffer[0]);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  return 0;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Try to receive n bytes
							 | 
						||
| 
								 | 
							
								int receive(int fd,int n) {
							 | 
						||
| 
								 | 
							
								  int a=0,b;
							 | 
						||
| 
								 | 
							
								  while(a<n) {
							 | 
						||
| 
								 | 
							
								    b= read(fd,inbuffer+a,n-a);
							 | 
						||
| 
								 | 
							
								    if(b==-1) {
							 | 
						||
| 
								 | 
							
								      printf("Read Error!\r\n");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								    } if (b==0) 
							 | 
						||
| 
								 | 
							
								      return a;
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								      if(inbuffer[a]==0xfa) 
							 | 
						||
| 
								 | 
							
								      	printf("<- Acknowledged\r\n");
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								        a=a+b;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return a;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Send cmd to the fd filehandle
							 | 
						||
| 
								 | 
							
								void command(int fd, unsigned char cmd) {
							 | 
						||
| 
								 | 
							
								  outbuffer[0]=cmd;
							 | 
						||
| 
								 | 
							
								  write(fd,outbuffer,1);
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								}  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Detect trackpoint device!
							 | 
						||
| 
								 | 
							
								int detectTP(int fd) {
							 | 
						||
| 
								 | 
							
								  fd_set set;
							 | 
						||
| 
								 | 
							
								  timeval timeout;
							 | 
						||
| 
								 | 
							
								  FD_ZERO(&set);
							 | 
						||
| 
								 | 
							
								  FD_SET(fd,&set);
							 | 
						||
| 
								 | 
							
								  timeout.tv_sec=0;
							 | 
						||
| 
								 | 
							
								  timeout.tv_usec=100000;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  printf("-> TP: Send extended ID\r\n");
							 | 
						||
| 
								 | 
							
								  command(fd,0xe1);
							 | 
						||
| 
								 | 
							
								  if (! getack(fd))
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    if(inbuffer[0]==0xfe) { // give it a second try
							 | 
						||
| 
								 | 
							
								      command(fd,0xe1);
							 | 
						||
| 
								 | 
							
								      if(getack(fd)) goto ack;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    printf("No trackpoint controller detected\r\n");  
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								  }  
							 | 
						||
| 
								 | 
							
								  ack:
							 | 
						||
| 
								 | 
							
								  int a=0;
							 | 
						||
| 
								 | 
							
								  while(select(FD_SETSIZE,&set,NULL,NULL,&timeout)) {
							 | 
						||
| 
								 | 
							
								    read(fd,inbuffer+a,1);
							 | 
						||
| 
								 | 
							
								    a++;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  char * version;
							 | 
						||
| 
								 | 
							
								  if(inbuffer[0]==0x01) {
							 | 
						||
| 
								 | 
							
								    switch(inbuffer[1]) {
							 | 
						||
| 
								 | 
							
								      case 0x01:
							 | 
						||
| 
								 | 
							
								      	version = "8E/98";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x02:
							 | 
						||
| 
								 | 
							
								      	version = "A4";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x03:
							 | 
						||
| 
								 | 
							
								      	version = "AB";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x04:
							 | 
						||
| 
								 | 
							
								      	version = "03";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x05:
							 | 
						||
| 
								 | 
							
								      	version = "B2/B4";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x06:
							 | 
						||
| 
								 | 
							
								      	version = "B1/B3/B5/B8/2B";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x07:
							 | 
						||
| 
								 | 
							
								      	version = "?";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x08:
							 | 
						||
| 
								 | 
							
								      	version = "?";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x09:
							 | 
						||
| 
								 | 
							
								      	version = "?";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x0A:
							 | 
						||
| 
								 | 
							
								      	version = "35";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x0B:
							 | 
						||
| 
								 | 
							
								      	version = "3A/3B";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x0C:
							 | 
						||
| 
								 | 
							
								      	version = "3C";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x0D:
							 | 
						||
| 
								 | 
							
								      	version = "3D";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      case 0x0E:
							 | 
						||
| 
								 | 
							
								      	version = "3E";
							 | 
						||
| 
								 | 
							
									break;
							 | 
						||
| 
								 | 
							
								      default:
							 | 
						||
| 
								 | 
							
								      	printf("Unrecognized ID: %02x\n",inbuffer[1]);
							 | 
						||
| 
								 | 
							
									return 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    printf("IBM Trackpoint controller detected. Version %s \r\n",version);
							 | 
						||
| 
								 | 
							
								    return 1;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    printf("No IBM trackpoint controller detected\r\n");  
							 | 
						||
| 
								 | 
							
								    printf("Extended ID: %02x %02x\r\n",inbuffer[0],inbuffer[1]);
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								// Reset PS/2 device
							 | 
						||
| 
								 | 
							
								int reset(int fd) {
							 | 
						||
| 
								 | 
							
								  command(fd,0xff);
							 | 
						||
| 
								 | 
							
								  printf("-> PS/2: Reset\r\n");
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								  receive(fd,2); 
							 | 
						||
| 
								 | 
							
								  if(inbuffer[0]==0xaa && inbuffer[1]==0x00) {
							 | 
						||
| 
								 | 
							
								    printf("<- PS/2: Succesfull initialization\r\n");
							 | 
						||
| 
								 | 
							
								    return 1;
							 | 
						||
| 
								 | 
							
								  } else
							 | 
						||
| 
								 | 
							
								    return 0;  
							 | 
						||
| 
								 | 
							
								}  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Get PS/2 ID
							 | 
						||
| 
								 | 
							
								int getdeviceid(int fd) {
							 | 
						||
| 
								 | 
							
								  command(fd,0xf2);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								  printf("-> PS/2: Get device ID\r\n");
							 | 
						||
| 
								 | 
							
								  if(receive(fd,1)==1) {
							 | 
						||
| 
								 | 
							
								    printf("<- PS/2: Device ID: %02x\n",inbuffer[0]);
							 | 
						||
| 
								 | 
							
								    return inbuffer[0];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void enabledatareport(int fd) {
							 | 
						||
| 
								 | 
							
								  command(fd, 0xf4);
							 | 
						||
| 
								 | 
							
								  printf("-> PS/2: (re)Enable data-reporting\r\n");
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								}  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void disabledatareport(int fd) {
							 | 
						||
| 
								 | 
							
								  command(fd, 0xf5);
							 | 
						||
| 
								 | 
							
								  printf("-> PS/2: Disable data-reporting\r\n");
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								}  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void setsamplerate(int fd, int rate) {
							 | 
						||
| 
								 | 
							
								  command(fd,0xf3);  
							 | 
						||
| 
								 | 
							
								  printf("-> PS/2: Set sample rate: %u\r\n",rate);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								  command(fd,rate);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								}  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void setresolution(int fd, int res) {
							 | 
						||
| 
								 | 
							
								  command(fd,0xe8);
							 | 
						||
| 
								 | 
							
								  printf("-> PS/2: Set resolution: %u\r\n",res);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								  command(fd,res);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void getstatus(int fd) {
							 | 
						||
| 
								 | 
							
								  command(fd,0xe9);
							 | 
						||
| 
								 | 
							
								  printf("-> Send status\r\n");
							 | 
						||
| 
								 | 
							
								  receive(fd,3);
							 | 
						||
| 
								 | 
							
								  printf("<- Status is: 0x%02x,0x%02x,0x%02x\n",inbuffer[0],inbuffer[1],inbuffer[2]);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void getlogiid(int fd) {
							 | 
						||
| 
								 | 
							
								  receive(fd,3);
							 | 
						||
| 
								 | 
							
								  unsigned char a = inbuffer[0];
							 | 
						||
| 
								 | 
							
								  unsigned char id = ((a >> 4) & 0x07) | ((a<<3) & 0x78);
							 | 
						||
| 
								 | 
							
								  printf("Logi-id: %d\r\n", id);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Put trackpoint device into transparent mode
							 | 
						||
| 
								 | 
							
								void enabletransparent(int fd) {
							 | 
						||
| 
								 | 
							
								  command(fd,0xe2);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								  command(fd,0x4e);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								  printf("-> TP: Set soft-transparent\r\n");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Get trackpoint device out of transparent mode
							 | 
						||
| 
								 | 
							
								// Notice the command gives not-ack because its in transparent mode,
							 | 
						||
| 
								 | 
							
								// just ignore these. After the command finishes to acknowledges are sent.
							 | 
						||
| 
								 | 
							
								void disabletransparent(int fd) {
							 | 
						||
| 
								 | 
							
								  command(fd,0xe2); 
							 | 
						||
| 
								 | 
							
								  //getack(fd);
							 | 
						||
| 
								 | 
							
								  command(fd,0xb9);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								  printf("-> TP: Cancel soft-transparent\r\n");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Detect external device on trackpoint controller
							 | 
						||
| 
								 | 
							
								bool detectExternal(int fd) {
							 | 
						||
| 
								 | 
							
								  command(fd,0xe2);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								  command(fd,0x21);
							 | 
						||
| 
								 | 
							
								  getack(fd);
							 | 
						||
| 
								 | 
							
								  receive(fd,1);
							 | 
						||
| 
								 | 
							
								  if(inbuffer[0] && 8) {
							 | 
						||
| 
								 | 
							
								    printf("<- TP: External device present\r\n");
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								  }  
							 | 
						||
| 
								 | 
							
								  else {
							 | 
						||
| 
								 | 
							
								    printf("<- TP: No external device\r\n");
							 | 
						||
| 
								 | 
							
								    return false;
							 | 
						||
| 
								 | 
							
								  }  
							 | 
						||
| 
								 | 
							
								}  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// IMPS/2 magic-initialization and detection
							 | 
						||
| 
								 | 
							
								bool detectIMPS(int fd) {
							 | 
						||
| 
								 | 
							
								  setsamplerate(fd,200);  
							 | 
						||
| 
								 | 
							
								  setsamplerate(fd,100);  
							 | 
						||
| 
								 | 
							
								  setsamplerate(fd,80);
							 | 
						||
| 
								 | 
							
								  if(getdeviceid(fd)==3) {
							 | 
						||
| 
								 | 
							
								    printf("IMPS/2 mouse detected\r\n");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int main() {
							 | 
						||
| 
								 | 
							
								  inbuffer = new unsigned char[200];
							 | 
						||
| 
								 | 
							
								  outbuffer = new unsigned char[200];
							 | 
						||
| 
								 | 
							
								  int fd = open("/dev/psaux", O_RDWR);
							 | 
						||
| 
								 | 
							
								  reset(fd);
							 | 
						||
| 
								 | 
							
								  // If kernel<2.4.9 remember to disable datareport, 
							 | 
						||
| 
								 | 
							
								  // in later kernels reset is enough
							 | 
						||
| 
								 | 
							
								  disabledatareport(fd);
							 | 
						||
| 
								 | 
							
								  sleep(1); // make sure we dont get any more confusing datareports.
							 | 
						||
| 
								 | 
							
								  if(detectTP(fd)) {
							 | 
						||
| 
								 | 
							
								    if(detectExternal(fd)) {
							 | 
						||
| 
								 | 
							
								      enabletransparent(fd); 
							 | 
						||
| 
								 | 
							
								      if(! detectIMPS(fd)) disabletransparent(fd);
							 | 
						||
| 
								 | 
							
								      setsamplerate(fd,200);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else
							 | 
						||
| 
								 | 
							
								    detectIMPS(fd);
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  enabledatareport(fd);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								  close(fd);
							 | 
						||
| 
								 | 
							
								}
							 |