May 30

All recent MacBooks have a Mulitouch touchpad. The raw finger data is not ‘officially’ avaialble, let alone available to Java apps. However some excellent native system digging found here, shows how to obtain the multitouch events, a big thank you to steike / Erling.

To make things simpler for Java development I have written a JNI library and wrapped that in an associated Java class based on the above work. The Java class implements an Observable Pattern, a base implementation is provided by the standard JDK. The end result is a very simple class which allows any number of Java listeners/observers to hook into the native multitouch events.

To excercise the API I have written a Swing and Console test client, I hope to add a WebStart (JNLP) wrapper. EDIT:  Webstart SwingTest can be found here.

Screenshot of Swing app:

swingtest1

Above you can see four of my mucky prints. The numbers represent the finger/blob id, which stays with the finger during contact; interestingly if you release and replace your finger back in the roughly the same point it tends to get the same id.
The ellipsoid shape and rotation are based on values that come from the trackpad.
The Mac trackpad can report up to 11 ‘blobs’ and also reports on size and angle, as well as a number of touch states such as hover – I have had to guess at the meanings of some of the state values as some are obvious, e.g. ‘pressed’, but some other seem very transitional e.g begining hover/ begining press.

An example of the Multitouch Observer API usage can be found below in the Console test Java source:

package com.alderstone.multitouch.mac.touchpad.tests;

import java.util.Observer;
import java.util.Observable;
import com.alderstone.multitouch.mac.touchpad.TouchpadObservable;
import com.alderstone.multitouch.mac.touchpad.Finger;
import com.alderstone.multitouch.mac.touchpad.FingerState;

public class ConsoleTest implements Observer {

        // Class that is resposible for registering with the Trackpad
        // and notifies registered clients of Touchpad Multitouch Events
        TouchpadObservable tpo;

        // Touchpad Multitouch update event handler,
        // called on single MT Finger event

        public void update( Observable obj, Object arg ) {

                // The event 'arg' is of type: com.alderstone.multitouch.mac.touchpad.Finger
                Finger f = (Finger) arg;

                int             frame = f.getFrame();
                double  timestamp = f.getTimestamp();
                int             id = f. getID();
                FingerState             state = f.getState();
                float   size = f.getSize();
                float   angRad = f.getAngleInRadians();
                int             angle = f.getAngle(); // return in Degrees
                float   majorAxis = f.getMajorAxis();
                float   minorAxis = f.getMinorAxis();
                float   x = f.getX();
                float   y = f.getY();
                float   dx = f.getXVelocity();
                float   dy = f.getYVelocity();

                System.out.println( "frame="+frame +
                               "\ttimestamp=" + timestamp +
                               "\tid=" +  id +
                               "\tstate=" + state +
                               "\tsize=" + size  +
                               "\tx,y=(" + x+ "," +  y+
                               ")\tdx,dy=(" + dx + "," + dy +")\t" +
                               "angle=" + angle  +
                               "majAxis=" + majorAxis  +
                               "\tminAxis=" + minorAxis);
        }       

        public void run() {
                tpo = TouchpadObservable.getInstance();
                tpo.addObserver(this);
        }

        public static void main(String[] args) {

                ConsoleTest ct = new ConsoleTest();
                ct.run();
                System.out.println("CTRL-C to exit.");
                try { while(true) {Thread.sleep(5000); }
                } catch (Exception e) {}
        }
}
Tagged with: