There's always time to play

Thursday, April 28, 2011

touchmoused: Logitech Touch Mouse server for Linux

Recently I was looking at a way to control the Mac Mini I have connected to my TV. I don't have a keyboard or mouse connected (only a gamepad), but I do have an iPod Touch. Soon I found Logitech Touch Mouse, a simple app providing a keyboard and mouse over the network. Of course Logitech isn't capable of delivering a Linux server for it's app, so I decided to write it myself.

After a quick Wireshark dump I started hacking away. Using the recently released Shairport as a reference I started hacking away on my first Perl program. This also being my first program where I had no documentation on protocol whatsoever, it took me a while to figure out I had to listen both on TCP and UDP. Then it also took me a while before I figured Perl doesn't write directly on a print statement unless autoflush is set on the file descriptor. I managed to find that one on a page detailing serial port communication with Perl.

When these hurdles were overcome I could really start interpreting events, sending them through to the Linux UInput facility. Today another big issue was fixed, mouse movement was broken until I added left mouse button support. So anyone trying to send mouse movements using uinput, be sure to enable left mouse button events!

Anyway, I've now come to a point where the Touch Mouse app can be effectively used as a trackpad replacement. Moving, clicking, (two-finger) scrolling, it all works. Also alphanumeric keys are working, Ctrl and Alt are working and some character keys are working. This also means I think I've come far enough to promote the app here on my blog, so anyone willing to try it out should move on to my github project page.


Anonymous said...

Cool! Just one question: why did you chose Perl? Just to learn the language?

Michael Croes said...

@Frank Groeneveld
You shared the Shairport announcement on Google Reader, so I looked at it and looked at the underlying code. I liked the simple way in which you can achieve a lot with a few lines (threading, socket handling). Also the code was a great guide on how to achieve some semi-complicated things, like setting up a SOAP server. I started out by copying parts of the Shairport code to get up and running quickly, having such an example to start with made it a lot easier. Of course I might as well had chosen either Python or Ruby, but I do think Perl was easier for me to pick up than going for those two. Last but not least Perl is available on about any system, so it should be easy for other people to use as well.

Anonymous said...

Hey. I just downloaded your script and installed as daemon. When I start it says it cant find /dev/uinput. A quick google search didnt help me, do you have any idea what to do?

Michael Croes said...

@Jon I guess it's just the path that's different from what's in the code (just open it in a text-editor), perhaps for your distribution the path is /dev/input/uinput.

Also, touchmoused doesn't work properly for me on Ubuntu releases newer than I was using at the time, still have to fix that. Will probably resume development soon though.


Michael Croes said...

I just made some changes to the touchmoused script. You should be able to change the path to the uinput device on the command line now. Also if you're using a 64 bit system the old version probably won't work, this one should. Please report if it works for you now! Also, feel free to file bugs about stuff that doesn't work (yet).


Unknown said...

It is great to see people taking initiative on thing like this, quick question though.. Running Fedora 16 I am having an odd issue where I am getting the following error..

[root@********** mycroes-touchmoused-efa4cc5]# ./touchmoused
Can't listen on port 4026: Address already in use at ./touchmoused line 285.
Avahi publishing failed! at ./touchmoused line 236.

I have made sure that nothing is running on port 4026 and have tried modifying the port to any other port, always returns the same failure.. Also I do NOT have iptables or selinux running on this machine.

Michael Croes said...


Thanks for the kind words. I guess the issue might not be the listening, but perhaps the avahi publishing failing? You could try to manually run the avahi publish line and see if it gives any errors. My guess is that publishing fails and then the code ends up at opening the tcp socket twice. I'll consider your comment as a bug report, when I have time I'll fix it.


Luk S. said...

Wow, this is just awesome.

After first minutes of testing I have only a few but not very important issues. Those are
1. some still missing keys e.g. "(", ")" or ":"
2. if you push the shift-button and type a letter, the program doesn't return to normal "unshifted" letter-size which I am used to normally.

All in all, your script perfectly fits my needs as I wanted to have a remote-control for my linux when using my notebook at my TV!

Thank you very very much.

(except for some signs this post is written with my iPhone while using your server)

UTL said...


I just install ubuntu 12.04
and this is my first linux...

So, the apt-get install, and configure
make make install is only I know

How can I install it ?

Michael Croes said...

Just download it, chmod +x and run it (as root, it needs access to /dev/uinput and it wants to register with avahi).


Marduk said...

You are awesome man! Just tried with my iPod Touch in Arch Linux and it works beautifully. Thanks a lot!

Unknown said...

Is that driver also working with the Logitech touchmouse ( )?
The name is so similar to the iphone app. I'm a bit puzzeled :)

Michael Croes said...

@Paul Sommer
No. Also, it's not a driver, it's a server application for the touchmouse app client.


Frank DeMarco said...

I had the address already in use error mentioned above and fixed it by installing avahi-utils:

apt-get install avahi-utils

It's working well now! Thanks for making it!

erduk said...
This comment has been removed by the author.
erduk said...

Hi there. I installed it to my Mk802 pc-on-a-stick running rikomagic lubuntu linux.

I can control it without using any usb port now.

Thanks a lot! And a lot!

മുക്കുവന്‍ said...


excellent tool. one question please.

I am seeing the same problem mr Notorous is seeing.did you get a chance to fix that problem?

Can't listen on port 4026: Address already in use at ./touchmoused line 285.
Avahi publishing failed! at ./touchmoused line 236.


മുക്കുവന്‍ said...

tried to install avahi and failed..he is my os and hardware info

[samu@samu bin]$ sudo ./touchmoused
Can't listen on port 4026: Address already in use at ./touchmoused line 284.
Avahi publishing failed! at ./touchmoused line 235.
[samu@samu bin]$ sudo yum install avahi-utils
Loaded plugins: langpacks, presto, refresh-packagekit
No package avahi-utils available.
Error: Nothing to do
[samu@samu bin]$ uname -a
Linux samu 3.6.10-4.fc18.i686 #1 SMP Tue Dec 11 18:24:49 UTC 2012 i686 i686 i386 GNU/Linux
[samu@samu bin]$ cat /etc/redhat-release
Fedora release 18 (Spherical Cow)

iimac13 said...

Hi Michael,

I have an MK808B running stock Android 4.2.2. I have root access, yet when I try running your script at the # prompt it tells me "perl not found, using default shell interpreter", then "touchmoused not found". Does this mean I need to install Perl? How can I run this?
Your files are at /dev/input

Michael Croes said...

This is made to use in conjunction with a mobile app from Logitech to control a desktop, laptop (or server even). Theoretically you could run it on your phone, but yes, you would need Perl to run it and I guess it wouldn't work well because all it does is sending keyboard or mouse events (which are not that useful on an Android phone).

Vague Rant said...

Hi Michael, just dropping a note here to say I'm using your Touch Mouse implementation on my brand new Raspberry Pi with an ancient iPhone 3G, because I don't have a spare mouse around for it. I'm just using it for the mouse side as I have a BlueTooth keyboard paired, but it's working great. Thought you might get a kick out of this.