home kinesia products products
Embedded Linux Information

  1. Building the 2.4.x Kernel Basics
  2. Network Configuration
  3. Developing Applications and Modules for uClinux 2.4.x
  4. Connection between Linux PC and 44B0X Target Board
  5. LCD Configuration
  6. Audio Configuration
  7. Sharp ARM 9 Root FS with FC
  8. Modifying SDL-1.2.11 to support USB mouse for ARM

Modifying SDL-1.2.11 to support USB mouse for ARM

Lee, Xiao Ping and Tong Lai Yu

Mouse and Touch Screen ( TS ) Input 

Mouse and TS have similar input mechanisms. For latest Linux versions, the devices in general are at For backward compatibility, the mouse may be accessed by /dev/input/mice, /dev/input/mouse0, /dev/input/mouse1, ...

You could test if the mouse works by, say,

moving the mouse around should display some crazy characters on the screen.

In ARM-9 board, we only see

  • /dev/input/event0
  • /dev/input/event1
  • In this case, event0 is for ts ( touch screen ) and event1 is for mouse or keyboard, depending on what you have plugged in the USB port. Again, can use the command "cat /dev/input/eventn" to test if you could open the device.

    SDL mouse support 

    SDL does not support USB mouse directly ( in PC, SDL utilizes X-window routine to handle the mouse but in our ARM board, we use the frame buffer routine directly ). So we need to modify SDL-1.2.11 as follows to support USB mouse and touch screen. Three files at src/video/fbcon need to be modified:

  • Add functions to handle mouse/ts in SDL_fbvideo.c ( note that we should use SELECT to handle I/O ):

  • Add function prototypes to header file SDL_fbevents_c.h:
    static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat)
    extern int FB_OpenEventX(_THIS);
    extern void FB_CloseEventX(_THIS);
    extern void FB_vgamousecallback(int button, int relative, int dx, int dy);
      

  • Add the following to SDL_fbevents.c:
    #include <linux/input.h>
    ....
    static int event0_fd = -1;
    static int event1_fd = -1;
    struct input_event ev0[64];
    struct input_event ev1[64];
    
    //for handling TS
    static void handle_event0(_THIS)
    {
      int button=0, x=0, y=0, realx=0, realy=0, i, rd;
    
      rd = read(event0_fd, ev0, sizeof(struct input_event) * 64);
      if( rd < sizeof(struct input_event) ) return;
    
      for (i = 0; i < rd / sizeof(struct input_event); i++)
      {
        if(ev0[i].type == 3 && ev0[i].code == 0) x = ev0[i].value;
        else if(ev0[i].type == 3 && ev0[i].code == 1) y = ev0[i].value;
        else if(ev0[i].type == 1 && ev0[i].code == 330) button = ev0[i].value << 2;
        else if(ev0[i].type == 0 && ev0[i].code == 0 && ev0[i].value == 0)
        {
        //need to define numbers in header for flexibility
    	realx = (950-y)*240/(950-70);
    	realy = (x-70)*320/(950-70);
    
    	if( realx < 0  ) realx = 0; 
    	if( realx > 240  ) realx = 240;
    	if( realy < 0  ) realy = 0; 
    	if( realy > 320  )realx = 320;
    	FB_vgamousecallback(button, 0, realx, realy);
        }		
      }
      return;
    }
    
    //for handling mouse
    static void handle_event1(_THIS)
    {
      int button=0, x=0, y=0, i, rd;
      rd = read(event1_fd, ev1, sizeof(struct input_event) * 64);
      if( rd < sizeof(struct input_event) ) return;
    
      for (i = 0; i < rd / sizeof(struct input_event); i++)
      {
        if(ev1[i].type == 2 && ev1[i].code == 0) x = ev1[i].value;
        else if(ev1[i].type == 2 && ev1[i].code == 1) y = ev1[i].value;
        else if(ev1[i].type == 1) {
    	if(ev1[i].code == 272) { 
    	  button &= ~0x4; 
    	  button |= ev1[i].value << 2; 
    	} else if(ev1[i].code == 273) {
    	  button &= ~0x1; 
    	  button |= ev1[i].value; 
            } else if(ev1[i].code == 274) { 
    	  button &= ~0x2; 
    	  button |= ev1[i].value << 1; 
            }
        } else if(ev1[i].type == 0 && ev1[i].code == 0 && ev1[i].value == 0) {
    	FB_vgamousecallback(button, 1, x, y);
    	x=0, y=0;
        }	
      }
    	
      return;
    }
    
    int FB_OpenEventX(_THIS)
    {
      event0_fd = open("/dev/input/event0", O_RDWR);
      event1_fd = open("/dev/input/event1", O_RDWR);
    
      if(event0_fd < 0 && event1_fd < 0)
        return 0;
    	
      return 1;
    }
    
    void FB_CloseEventX(_THIS)
    {
      if ( event0_fd > 0 ) {
        close(event0_fd);
      }
    
      if ( event1_fd > 0 ) {
        close(event1_fd);
      }
    
      event0_fd = -1;
      event1_fd = -1;
    }
    ....