X-Git-Url: https://git.saurik.com/veency.git/blobdiff_plain/20b5b9d9998228be7c13d8742cd425f3662882cf..1c6eb1765c7dac2819bfe7fe48ef619edbc1b792:/Tweak.mm diff --git a/Tweak.mm b/Tweak.mm index 7eaaea9..1b99b5b 100644 --- a/Tweak.mm +++ b/Tweak.mm @@ -52,6 +52,7 @@ extern "C" { #include "SpringBoardAccess.h" } +MSClassHook(BKAccessibility) MSClassHook(UIApplication) @interface UIApplication (Apple) @@ -61,6 +62,8 @@ MSClassHook(UIApplication) @interface CAWindowServerDisplay : NSObject - (mach_port_t) clientPortAtPosition:(CGPoint)position; +- (unsigned) contextIdAtPosition:(CGPoint)position; +- (mach_port_t) taskPortOfContextId:(unsigned)context; @end @interface CAWindowServer : NSObject @@ -91,6 +94,14 @@ MSClassHook(UIApplication) - (void) removeStatusBarItem:(NSString *)item; @end +@interface BKHIDClientConnectionManager : NSObject +- () clientForTaskPort:(mach_port_t)port; +@end + +@interface BKAccessibility : NSObject ++ (BKHIDClientConnectionManager *) _eventRoutingClientConnectionManager; +@end + typedef void *CoreSurfaceBufferRef; extern CFStringRef kCoreSurfaceBufferGlobal; @@ -129,12 +140,22 @@ extern "C" void IOMobileFramebufferIsMainDisplay(IOMobileFramebufferRef connect, typedef CFTypeRef IOHIDEventRef; typedef CFTypeRef IOHIDEventSystemClientRef; +typedef CFTypeRef IOHIDEventSystemConnectionRef; extern "C" { IOHIDEventRef IOHIDEventCreateKeyboardEvent(CFAllocatorRef allocator, uint64_t time, uint16_t page, uint16_t usage, Boolean down, IOHIDEventOptionBits flags); + + IOHIDEventRef IOHIDEventCreateDigitizerEvent(CFAllocatorRef allocator, uint64_t timeStamp, IOHIDDigitizerTransducerType type, uint32_t index, uint32_t identity, uint32_t eventMask, uint32_t buttonMask, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOHIDFloat tipPressure, IOHIDFloat barrelPressure, Boolean range, Boolean touch, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateDigitizerFingerEvent(CFAllocatorRef allocator, uint64_t timeStamp, uint32_t index, uint32_t identity, uint32_t eventMask, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOHIDFloat tipPressure, IOHIDFloat twist, Boolean range, Boolean touch, IOOptionBits options); + IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator); + + void IOHIDEventAppendEvent(IOHIDEventRef parent, IOHIDEventRef child); + void IOHIDEventSetIntegerValue(IOHIDEventRef event, IOHIDEventField field, int value); void IOHIDEventSetSenderID(IOHIDEventRef event, uint64_t sender); + void IOHIDEventSystemClientDispatchEvent(IOHIDEventSystemClientRef client, IOHIDEventRef event); + void IOHIDEventSystemConnectionDispatchEvent(IOHIDEventSystemConnectionRef connection, IOHIDEventRef event); } static size_t width_; @@ -586,12 +607,16 @@ static void VNCPointerOld(int buttons, int x, int y, CGPoint location, int diff, mach_port_deallocate(mach_task_self(), purple); } +static void VNCSetSender(IOHIDEventRef event) { + IOHIDEventSetSenderID(event, 0xDEFACEDBEEFFECE5); +} + static void VNCSendHIDEvent(IOHIDEventRef event) { static IOHIDEventSystemClientRef client_(NULL); if (client_ == NULL) client_ = IOHIDEventSystemClientCreate(kCFAllocatorDefault); - IOHIDEventSetSenderID(event, 0xDEFACEDBEEFFECE5); + VNCSetSender(event); IOHIDEventSystemClientDispatchEvent(client_, event); CFRelease(event); } @@ -604,8 +629,52 @@ static void VNCPointerNew(int buttons, int x, int y, CGPoint location, int diff, if ((diff & 0x02) != 0) VNCSendHIDEvent(IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, mach_absolute_time(), kHIDPage_Consumer, kHIDUsage_Csmr_Power, (buttons & 0x02) != 0, 0)); - if (twas != tis || tis) { - } + uint32_t handm; + uint32_t fingerm; + + if (twas == 0 && tis == 1) { + handm = kIOHIDDigitizerEventRange | kIOHIDDigitizerEventTouch | kIOHIDDigitizerEventIdentity; + fingerm = kIOHIDDigitizerEventRange | kIOHIDDigitizerEventTouch; + } else if (twas == 1 && tis == 1) { + handm = kIOHIDDigitizerEventPosition; + fingerm = kIOHIDDigitizerEventPosition; + } else if (twas == 1 && tis == 0) { + handm = kIOHIDDigitizerEventRange | kIOHIDDigitizerEventTouch | kIOHIDDigitizerEventIdentity | kIOHIDDigitizerEventPosition; + fingerm = kIOHIDDigitizerEventRange | kIOHIDDigitizerEventTouch; + } else return; + + CAWindowServer *server([CAWindowServer serverIfRunning]); + if (server == nil) + return; + + CAWindowServerDisplay *display([[server displays] objectAtIndex:0]); + if (display == nil) + return; + + unsigned context([display contextIdAtPosition:CGPointMake(x, y)]); + mach_port_t port([display taskPortOfContextId:context]); + if (port == MACH_PORT_NULL) + return; + + IOHIDEventSystemConnectionRef connection([[$BKAccessibility _eventRoutingClientConnectionManager] clientForTaskPort:port]); + if (connection == NULL) + return; + + // XXX: I guess this isn't ambiguous, and it works + IOHIDFloat xf(x); + IOHIDFloat yf(y); + + IOHIDEventRef hand(IOHIDEventCreateDigitizerEvent(kCFAllocatorDefault, mach_absolute_time(), kIOHIDDigitizerTransducerTypeHand, 1<<22, 1, handm, 0, xf, yf, 0, 0, 0, 0, 0, 0)); + IOHIDEventSetIntegerValue(hand, kIOHIDEventFieldIsBuiltIn, true); + IOHIDEventSetIntegerValue(hand, kIOHIDEventFieldDigitizerIsDisplayIntegrated, true); + + IOHIDEventRef finger(IOHIDEventCreateDigitizerFingerEvent(kCFAllocatorDefault, mach_absolute_time(), 3, 2, fingerm, xf, yf, 0, 0, 0, tis, tis, 0)); + IOHIDEventAppendEvent(hand, finger); + CFRelease(finger); + + VNCSetSender(hand); + IOHIDEventSystemConnectionDispatchEvent(connection, hand); + CFRelease(hand); } GSEventRef (*$GSEventCreateKeyEvent)(int, CGPoint, CFStringRef, CFStringRef, id, UniChar, short, short); @@ -617,6 +686,17 @@ static void VNCKeyboardNew(rfbBool down, rfbKeySym key, rfbClientPtr client) { uint16_t usage; switch (key) { + case XK_exclam: case XK_1: usage = kHIDUsage_Keyboard1; break; + case XK_at: case XK_2: usage = kHIDUsage_Keyboard2; break; + case XK_numbersign: case XK_3: usage = kHIDUsage_Keyboard3; break; + case XK_dollar: case XK_4: usage = kHIDUsage_Keyboard4; break; + case XK_percent: case XK_5: usage = kHIDUsage_Keyboard5; break; + case XK_asciicircum: case XK_6: usage = kHIDUsage_Keyboard6; break; + case XK_ampersand: case XK_7: usage = kHIDUsage_Keyboard7; break; + case XK_asterisk: case XK_8: usage = kHIDUsage_Keyboard8; break; + case XK_parenleft: case XK_9: usage = kHIDUsage_Keyboard9; break; + case XK_parenright: case XK_0: usage = kHIDUsage_Keyboard0; break; + case XK_A: case XK_a: usage = kHIDUsage_KeyboardA; break; case XK_B: case XK_b: usage = kHIDUsage_KeyboardB; break; case XK_C: case XK_c: usage = kHIDUsage_KeyboardC; break;