These are the mouse protocols you had to send out on the serial port. Quite simple. The only complicated part is, you have to output relative coordinates as the mouse is a relative device.
It's easiest not to decode the relative coordinates coming from the USB mouse, but sample the event interface directly and just forward them:
#!/usr/bin/tclsh
## Open /dev/input/eventX in non-buffered, no-translation mode.
set efd [open [lindex $::argv 0] r]
fconfigure $efd -translation binary -buffering none
## Open /dev/ttyAMAy in non-buffered, no-translation mode, with Microsoft Mouse UART parameters.
set sfd [open [lindex $::argv 1] r+]
fconfigure $sfd -translation binary -buffering none -blocking false -mode 1200,n,7,1
## Button states and coordinates.
set bl 0
set br 0
set rx 0
set ry 0
## Process a mouse event from /dev/input/eventX.
proc sampleEvent {} {
## Exit program when device fails (mouse pulled from USB.)
if {[eof $::efd]} exit
## Read event record from kernel driver.
## Skip both timestamps, decode type, code, value fields.
binary scan \
[read $::efd [expr {2*$::tcl_platform(wordSize)+8}]] \
x[expr {2*$::tcl_platform(wordSize)}]ssi \
type code value
## Process event by type.
switch -- $type {
0 {
## Process sync event.
## Send out mouse data on serial interface. Microsoft mouse protocol.
set b1 [expr {0x40 | ($::bl&0x01)<<5 | ($::br&0x01)<<4 | ($::ry&0xc0)>>4 | ($::rx&0xc0)>>6}]
set b2 [expr {$::rx&0x3f}]
set b3 [expr {$::ry&0x3f}]
puts -nonewline $::sfd [binary format ccc $b1 $b2 $b3]
## Reset relative coordinates.
set ::rx 0
set ::ry 0
}
1 {
## Process button event.
switch -- $code {
272 {set ::bl $value}
273 {set ::br $value}
}
}
2 {
## Process relative event.
switch -- $code {
0 {set ::rx $value}
1 {set ::ry $value}
}
}
}
}
## Sample event whenever the device node becomes readable.
fileevent $efd readable sampleEvent
## Start Tcl event loop.
vwait endless
Call with evdev2serialmouse /dev/input/event0 /dev/ttyAMA0
or whatever your device nodes are.