Skip to content

Instantly share code, notes, and snippets.

@lericson
Created November 17, 2009 10:01
Show Gist options
  • Save lericson/236798 to your computer and use it in GitHub Desktop.
Save lericson/236798 to your computer and use it in GitHub Desktop.
import time
import ctypes
import threading
from ctypes.util import find_library
CFArrayRef = ctypes.c_void_p
CFMutableArrayRef = ctypes.c_void_p
CFIndex = ctypes.c_long
MultitouchSupport = ctypes.CDLL("/System/Library/PrivateFrameworks/MultitouchSupport.framework/MultitouchSupport")
CFArrayGetCount = MultitouchSupport.CFArrayGetCount
CFArrayGetCount.argtypes = [CFArrayRef]
CFArrayGetCount.restype = CFIndex
CFArrayGetValueAtIndex = MultitouchSupport.CFArrayGetValueAtIndex
CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
CFArrayGetValueAtIndex.restype = ctypes.c_void_p
MTDeviceCreateList = MultitouchSupport.MTDeviceCreateList
MTDeviceCreateList.argtypes = []
MTDeviceCreateList.restype = CFMutableArrayRef
class MTPoint(ctypes.Structure):
_fields_ = [("x", ctypes.c_float),
("y", ctypes.c_float)]
class MTVector(ctypes.Structure):
_fields_ = [("position", MTPoint),
("velocity", MTPoint)]
class MTData(ctypes.Structure):
_fields_ = [
("frame", ctypes.c_int),
("timestamp", ctypes.c_double),
("identifier", ctypes.c_int),
("state", ctypes.c_int), # Current state (of unknown meaning).
("unknown1", ctypes.c_int),
("unknown2", ctypes.c_int),
("normalized", MTVector), # Normalized position and vector of
# the touch (0 to 1).
("size", ctypes.c_float), # The area of the touch.
("unknown3", ctypes.c_int),
# The following three define the ellipsoid of a finger.
("angle", ctypes.c_float),
("major_axis", ctypes.c_float),
("minor_axis", ctypes.c_float),
("unknown4", MTVector),
("unknown5_1", ctypes.c_int),
("unknown5_2", ctypes.c_int),
("unknown6", ctypes.c_float),
]
MTDataRef = ctypes.POINTER(MTData)
MTContactCallbackFunction = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, MTDataRef,
ctypes.c_int, ctypes.c_double, ctypes.c_int)
MTDeviceRef = ctypes.c_void_p
MTRegisterContactFrameCallback = MultitouchSupport.MTRegisterContactFrameCallback
MTRegisterContactFrameCallback.argtypes = [MTDeviceRef, MTContactCallbackFunction]
MTRegisterContactFrameCallback.restype = None
MTDeviceStart = MultitouchSupport.MTDeviceStart
MTDeviceStart.argtypes = [MTDeviceRef, ctypes.c_int]
MTDeviceStart.restype = None
###
@MTContactCallbackFunction
def my_callback(device, data_ptr, n_fingers, timestamp, frame):
#print threading.current_thread(), device, data_ptr, n_fingers, timestamp, frame
for i in xrange(n_fingers):
data = data_ptr[i]
d = "x=%.2f, y=%.2f" % (data.normalized.position.x * 100,
data.normalized.position.y * 100)
print "%d: %s" % (i, d)
return 0
devices = MultitouchSupport.MTDeviceCreateList()
num_devices = CFArrayGetCount(devices)
print "num_devices =", num_devices
for i in xrange(num_devices):
device = CFArrayGetValueAtIndex(devices, i)
print "device #%d: %016x" % (i, device)
MTRegisterContactFrameCallback(device, my_callback)
MTDeviceStart(device, 0)
while threading.active_count():
# Why sleep instead of join? Ask David Beazley.
time.sleep(0.125)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment