mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
devdraw: dynamic discovery of MultiTouch devices
R=rsc CC=plan9port.codebot http://codereview.appspot.com/4653041
This commit is contained in:
parent
e055ceb20b
commit
5e83be0dbf
2 changed files with 107 additions and 8 deletions
|
@ -17,6 +17,7 @@ Fazlul Shahriar <fshahriar@gmail.com>
|
|||
J.R. Mauro <jrm8005@gmail.com>
|
||||
Jeff Sickel <jas@corpus-callosum.com>
|
||||
Kris Maglione <jg@suckless.org>
|
||||
Marius Eriksen <marius.eriksen@gmail.com>
|
||||
Mathieu Lonjaret <lejatorn@gmail.com>
|
||||
Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
|
||||
Michael Teichgräber <mt4swm@googlemail.com>
|
||||
|
|
|
@ -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
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue