devdraw: dynamic discovery of MultiTouch devices

R=rsc
CC=plan9port.codebot
http://codereview.appspot.com/4653041
This commit is contained in:
Marius Eriksen 2011-06-20 14:14:53 -04:00 committed by Russ Cox
parent e055ceb20b
commit 5e83be0dbf
2 changed files with 107 additions and 8 deletions

View file

@ -17,6 +17,7 @@ Fazlul Shahriar <fshahriar@gmail.com>
J.R. Mauro <jrm8005@gmail.com> J.R. Mauro <jrm8005@gmail.com>
Jeff Sickel <jas@corpus-callosum.com> Jeff Sickel <jas@corpus-callosum.com>
Kris Maglione <jg@suckless.org> Kris Maglione <jg@suckless.org>
Marius Eriksen <marius.eriksen@gmail.com>
Mathieu Lonjaret <lejatorn@gmail.com> Mathieu Lonjaret <lejatorn@gmail.com>
Mathieu Lonjaret <mathieu.lonjaret@gmail.com> Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
Michael Teichgräber <mt4swm@googlemail.com> Michael Teichgräber <mt4swm@googlemail.com>

View file

@ -2,6 +2,10 @@
#define Rect OSXRect #define Rect OSXRect
#define Cursor OSXCursor #define Cursor OSXCursor
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#ifdef MULTITOUCH
#include <IOKit/IOKitLib.h>
#include <IOKit/hidsystem/IOHIDShared.h>
#endif
#undef Rect #undef Rect
#undef Point #undef Point
#undef Cursor #undef Cursor
@ -26,6 +30,7 @@ AUTOFRAMEWORK(Cocoa)
#ifdef MULTITOUCH #ifdef MULTITOUCH
AUTOFRAMEWORK(MultitouchSupport) AUTOFRAMEWORK(MultitouchSupport)
AUTOFRAMEWORK(IOKit)
#endif #endif
#define panic sysfatal #define panic sysfatal
@ -115,11 +120,15 @@ CFMutableArrayRef MTDeviceCreateList(void);
//registers a device's frame callback to your callback function //registers a device's frame callback to your callback function
void MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction); void MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction);
void MTUnregisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction);
//start sending events //start sending events
void MTDeviceStart(MTDeviceRef, int); void MTDeviceStart(MTDeviceRef, int);
void MTDeviceStop(MTDeviceRef); void MTDeviceStop(MTDeviceRef);
MTDeviceRef MTDeviceCreateFromService(io_service_t);
io_service_t MTDeviceGetService(MTDeviceRef);
#define kNTracks 10 #define kNTracks 10
struct TouchTrack { struct TouchTrack {
int id; int id;
@ -280,25 +289,114 @@ enum
void screeninit(void); void screeninit(void);
void _flushmemscreen(Rectangle r); void _flushmemscreen(Rectangle r);
#ifdef MULTITOUCH
static void static void
InitMultiTouch(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
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 #ifdef MULTITOUCH
IONotificationPortRef port;
CFRunLoopSourceRef source;
io_iterator_t iter;
kern_return_t kr;
io_object_t obj;
int i; int i;
/*
* Setup multitouch queues
*/
if(!multitouch) if(!multitouch)
return; return;
for(i = 0; i<kNTracks; ++i) osx.devicelist = [[NSMutableArray alloc] init];
for(i = 0; i < kNTracks; ++i)
tracks[i].id = -1; tracks[i].id = -1;
osx.devicelist = (NSMutableArray*)MTDeviceCreateList(); //grab our device list port = IONotificationPortCreate(kIOMasterPortDefault);
for(i = 0; i<[osx.devicelist count]; i++) { //iterate available devices if(port == nil){
MTRegisterContactFrameCallback([osx.devicelist objectAtIndex:i], touchCallback); //assign callback for device 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 #endif
} }