Skip to content

Instantly share code, notes, and snippets.

@EthanArbuckle
Created September 9, 2015 02:30
Show Gist options
  • Save EthanArbuckle/646840fb976977393121 to your computer and use it in GitHub Desktop.
Save EthanArbuckle/646840fb976977393121 to your computer and use it in GitHub Desktop.
a gross way to use raw iokit events to detect pinch gestures
#import <UIKit/UIKit.h>
#include <IOKit/hid/IOHIDEventSystem.h>
#include <IOKit/hid/IOHIDEventSystemClient.h>
#include "CDTContextHostProvider.h"
#include <stdio.h>
#include <dlfcn.h>
UIView *contextView;
int IOHIDEventSystemClientSetMatching(IOHIDEventSystemClientRef client, CFDictionaryRef match);
CFArrayRef IOHIDEventSystemClientCopyServices(IOHIDEventSystemClientRef, int);
typedef struct __IOHIDServiceClient * IOHIDServiceClientRef;
int IOHIDServiceClientSetProperty(IOHIDServiceClientRef, CFStringRef, CFNumberRef);
typedef void* (*clientCreatePointer)(const CFAllocatorRef);
extern "C" void BKSHIDServicesCancelTouchesOnMainDisplay();
void touch_event(void* target, void* refcon, IOHIDServiceRef service, IOHIDEventRef event) {
if (IOHIDEventGetType(event) == kIOHIDEventTypeDigitizer) {
//get child events (individual finger)
NSArray *children = (NSArray *)IOHIDEventGetChildren(event);
if ([children count] == 2) { //pinch
CGFloat p1x = IOHIDEventGetFloatValue((__IOHIDEvent *)children[0], (IOHIDEventField)kIOHIDEventFieldDigitizerX);
CGFloat p1y = IOHIDEventGetFloatValue((__IOHIDEvent *)children[0], (IOHIDEventField)kIOHIDEventFieldDigitizerY);
CGFloat p2x = IOHIDEventGetFloatValue((__IOHIDEvent *)children[1], (IOHIDEventField)kIOHIDEventFieldDigitizerX);
CGFloat p2y = IOHIDEventGetFloatValue((__IOHIDEvent *)children[1], (IOHIDEventField)kIOHIDEventFieldDigitizerY);
CGFloat diff = sqrt(((p2x - p1x) * (p2x - p1x)) + ((p2y - p1y) * (p2y - p1y)));
diff = (diff > 1) ? 1 : diff;
NSLog(@"pinch : %f", diff);
//do stuff
if (contextView) {
//block other touches
BKSHIDServicesCancelTouchesOnMainDisplay();
//resize app window
[contextView setTransform:CGAffineTransformMakeScale(diff, diff)];
}
}
}
}
%hook SBLockScreenManager
- (void)_finishUIUnlockFromSource:(int)source withOptions:(id)options {
%orig;
//my IOKit's symbol table is fucked so we doin lookups
clientCreatePointer clientCreate;
void *handle = dlopen(0, 9);
*(void**)(&clientCreate) = dlsym(handle,"IOHIDEventSystemClientCreate");
IOHIDEventSystemClientRef ioHIDEventSystem = (__IOHIDEventSystemClient *)clientCreate(kCFAllocatorDefault);
IOHIDEventSystemClientScheduleWithRunLoop(ioHIDEventSystem, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
IOHIDEventSystemClientRegisterEventCallback(ioHIDEventSystem, (IOHIDEventSystemClientEventCallback)touch_event, NULL, NULL);
//throw a weather host view up on unlock to demonstrate
CDTContextHostProvider *contextProvider = [[CDTContextHostProvider alloc] init];
contextView = [contextProvider hostViewForApplicationWithBundleID:@"com.apple.weather"];
[contextProvider setStatusBarHidden:@(1) onApplicationWithBundleID:@"com.apple.weather"];
[contextView setTransform:CGAffineTransformMakeScale(.6, .6)];
[[[UIApplication sharedApplication] keyWindow] addSubview:contextView];
}
%end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment