diff options
author | Marius Eriksen <marius.eriksen@gmail.com> | 2011-06-20 14:14:53 -0400 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2011-06-20 14:14:53 -0400 |
commit | 5e83be0dbf9667f7d11a167f9eacc31837ed4c7d (patch) | |
tree | d731ef01235a2830e5031528709e4701e3721370 /src | |
parent | e055ceb20bd94caff3b07e64a051ab3a899c0463 (diff) | |
download | plan9port-5e83be0dbf9667f7d11a167f9eacc31837ed4c7d.tar.gz plan9port-5e83be0dbf9667f7d11a167f9eacc31837ed4c7d.tar.bz2 plan9port-5e83be0dbf9667f7d11a167f9eacc31837ed4c7d.zip |
devdraw: dynamic discovery of MultiTouch devices
R=rsc
CC=plan9port.codebot
http://codereview.appspot.com/4653041
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/devdraw/osx-screen-carbon.m | 114 |
1 files changed, 106 insertions, 8 deletions
diff --git a/src/cmd/devdraw/osx-screen-carbon.m b/src/cmd/devdraw/osx-screen-carbon.m index 2f295a03..93d58ce0 100644 --- a/src/cmd/devdraw/osx-screen-carbon.m +++ b/src/cmd/devdraw/osx-screen-carbon.m @@ -2,6 +2,10 @@ #define Rect OSXRect #define Cursor OSXCursor #include <Carbon/Carbon.h> +#ifdef MULTITOUCH +#include <IOKit/IOKitLib.h> +#include <IOKit/hidsystem/IOHIDShared.h> +#endif #undef Rect #undef Point #undef Cursor @@ -26,6 +30,7 @@ AUTOFRAMEWORK(Cocoa) #ifdef MULTITOUCH AUTOFRAMEWORK(MultitouchSupport) +AUTOFRAMEWORK(IOKit) #endif #define panic sysfatal @@ -115,11 +120,15 @@ CFMutableArrayRef MTDeviceCreateList(void); //registers a device's frame callback to your callback function void MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction); +void MTUnregisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction); //start sending events void MTDeviceStart(MTDeviceRef, int); void MTDeviceStop(MTDeviceRef); +MTDeviceRef MTDeviceCreateFromService(io_service_t); +io_service_t MTDeviceGetService(MTDeviceRef); + #define kNTracks 10 struct TouchTrack { int id; @@ -280,25 +289,114 @@ enum void screeninit(void); void _flushmemscreen(Rectangle r); +#ifdef MULTITOUCH +static void +RegisterMultitouch(void *ctx, io_iterator_t iter) +{ + io_object_t io; + MTDeviceRef dev; + + while((io = IOIteratorNext(iter)) != 0){ + dev = MTDeviceCreateFromService(io); + if (dev != nil){ + MTRegisterContactFrameCallback(dev, touchCallback); + [osx.devicelist addObject:dev]; + if(osx.active) + MTDeviceStart(dev, 0); + } + + IOObjectRelease(io); + } +} + static void -InitMultiTouch(void) +UnregisterMultitouch(void *ctx, io_iterator_t iter) +{ + io_object_t io; + MTDeviceRef dev; + int i; + + while((io = IOIteratorNext(iter)) != 0){ + for(i = 0; i < [osx.devicelist count]; i++){ + dev = [osx.devicelist objectAtIndex:i]; + if(IOObjectIsEqualTo(MTDeviceGetService(dev), io)){ + if(osx.active) + MTDeviceStop(dev); + MTUnregisterContactFrameCallback(dev, touchCallback); + [osx.devicelist removeObjectAtIndex:i]; + break; + } + } + + IOObjectRelease(io); + } +} + +#endif /*MULTITOUCH*/ + +static void +InitMultiTouch() { #ifdef MULTITOUCH + IONotificationPortRef port; + CFRunLoopSourceRef source; + io_iterator_t iter; + kern_return_t kr; + io_object_t obj; int i; - /* - * Setup multitouch queues - */ if(!multitouch) return; - for(i = 0; i<kNTracks; ++i) + osx.devicelist = [[NSMutableArray alloc] init]; + + for(i = 0; i < kNTracks; ++i) tracks[i].id = -1; - osx.devicelist = (NSMutableArray*)MTDeviceCreateList(); //grab our device list - for(i = 0; i<[osx.devicelist count]; i++) { //iterate available devices - MTRegisterContactFrameCallback([osx.devicelist objectAtIndex:i], touchCallback); //assign callback for device + port = IONotificationPortCreate(kIOMasterPortDefault); + if(port == nil){ + fprint(2, "failed to get an IO notification port\n"); + return; + } + + source = IONotificationPortGetRunLoopSource(port); + if(source == nil){ + fprint(2, "failed to get loop source for port"); + return; } + + CFRunLoopAddSource( + (CFRunLoopRef)GetCFRunLoopFromEventLoop(GetMainEventLoop()), + source, + kCFRunLoopDefaultMode); + + kr = IOServiceAddMatchingNotification( + port, kIOTerminatedNotification, + IOServiceMatching("AppleMultitouchDevice"), + &UnregisterMultitouch, + nil, &iter); + + if(kr != KERN_SUCCESS){ + fprint(2, "failed to add termination notification\n"); + return; + } + + /* Arm the notification */ + while((obj = IOIteratorNext(iter)) != 0) + IOObjectRelease(obj); + + kr = IOServiceAddMatchingNotification( + port, kIOMatchedNotification, + IOServiceMatching("AppleMultitouchDevice"), + &RegisterMultitouch, + nil, &iter); + + if(kr != KERN_SUCCESS){ + fprint(2, "failed to add matching notification\n"); + return; + } + + RegisterMultitouch(nil, iter); #endif } |