ios12-nt
This commit is contained in:
parent
39a5bcfec7
commit
1acdf1a070
@ -6,5 +6,5 @@ Author: XYZShell
|
||||
Section: Utilities
|
||||
Tag: role::developer
|
||||
Architecture: iphoneos-arm
|
||||
Version: 0.0.7-10-51+debug
|
||||
Installed-Size: 1624
|
||||
Version: 0.0.7-10-53+debug
|
||||
Installed-Size: 1600
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
./packages/com.xyzshell.ioscontrol_0.0.7-10-51+debug_iphoneos-arm.deb
|
||||
./packages/com.xyzshell.ioscontrol_0.0.7-10-53+debug_iphoneos-arm.deb
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
51
|
||||
53
|
||||
@ -13,7 +13,6 @@
|
||||
#import "XSHelper.h"
|
||||
#import "XSHackIos.h"
|
||||
#import "XSHttpHelper.h"
|
||||
#import "XSIosTouch.h"
|
||||
#import "MyAdServer.h"
|
||||
#import "MyAdTask2.h"
|
||||
#import "MyEventBus.h"
|
||||
@ -158,7 +157,7 @@
|
||||
self.ip = [[XSPhoneInfo sharedInstance] IPAddress];
|
||||
self.remoteIp = [[XSPhoneInfo sharedInstance] remoteIp];
|
||||
self.diskSize = [[XSPhoneInfo sharedInstance] IPhoneStatus];
|
||||
self.message = @"251021a";
|
||||
self.message = @"251030-nt";
|
||||
// 构建请求数据
|
||||
NSDictionary *heartbeatData = [self constructHeartbeatData];
|
||||
if (!heartbeatData) {
|
||||
@ -265,62 +264,7 @@
|
||||
NSLog(@"No foreground app detected");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取触摸实例
|
||||
XSIosTouch *touch = [XSIosTouch sharedInstance];
|
||||
if (!touch) {
|
||||
NSLog(@"Touch instance not available");
|
||||
return;
|
||||
}
|
||||
|
||||
// 标记开始处理触摸
|
||||
self.isProcessingTouch = YES;
|
||||
__weak typeof(self) weakSelf = self;
|
||||
// 执行第一次点击
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@try {
|
||||
// 检查最小触摸间隔
|
||||
NSTimeInterval currentTime = [XSHelper getCurTime];
|
||||
if (currentTime - weakSelf.lastTouchTime < 0.05) { // 50ms最小间隔
|
||||
return;
|
||||
}
|
||||
|
||||
weakSelf.lastTouchTime = currentTime;
|
||||
[touch Tap:1 x:244 y:766];
|
||||
|
||||
// 延迟执行第二次点击
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)),
|
||||
dispatch_get_main_queue(), ^{
|
||||
@try {
|
||||
// 再次检查前台应用
|
||||
NSString *currentAppId = XSFrontMostAppId();
|
||||
if (!currentAppId.length) {
|
||||
NSLog(@"App not in foreground for second tap");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查最小触摸间隔
|
||||
NSTimeInterval newCurrentTime = [XSHelper getCurTime];
|
||||
if (newCurrentTime - weakSelf.lastTouchTime < 0.05) {
|
||||
return;
|
||||
}
|
||||
|
||||
weakSelf.lastTouchTime = newCurrentTime;
|
||||
[touch Tap:1 x:382 y:766];
|
||||
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error in second tap: %@", exception);
|
||||
} @finally {
|
||||
// 确保处理状态被重置
|
||||
weakSelf.isProcessingTouch = NO;
|
||||
}
|
||||
});
|
||||
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error in first tap: %@", exception);
|
||||
weakSelf.isProcessingTouch = NO;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// 添加清理方法
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#import "XSHackIos.h"
|
||||
#import "MyScriptTask.h"
|
||||
#import "MyEventBus.h"
|
||||
#import "XSIosTouch.h"
|
||||
#import "XSHttpHelper.h"
|
||||
#import "MyAdTask2.h"
|
||||
#import "MyAdServer.h"
|
||||
@ -284,7 +283,6 @@
|
||||
float nx = [x floatValue];
|
||||
float ny = [y floatValue];
|
||||
//[[[XSJsApi alloc] init] tap:10 x:nx y:ny];
|
||||
[[XSIosTouch sharedInstance] Tap:10 x:nx y:ny];
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -305,10 +303,6 @@
|
||||
if (dic && ![dic isEqual:[NSNull null]]) {
|
||||
NSNumber *k = dic[@"key"];
|
||||
long key = [k longValue];
|
||||
XSIosTouch *touch = [[XSIosTouch alloc] init];
|
||||
[touch KeyDown:key];
|
||||
usleep(5000);
|
||||
[touch KeyDown:key];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "IPhoneHertbeat.h"
|
||||
#import "XSHackIos.h"
|
||||
#import "XSIosTouch.h"
|
||||
#import "XSHelper.h"
|
||||
#import "XSPhoneInfo.h"
|
||||
#import "XSPhoneConfig.h"
|
||||
@ -488,10 +487,6 @@ BOOL myadTaskManualStop = NO;
|
||||
}
|
||||
|
||||
- (void) tap: (int) i x:(int)x y:(int)y {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
XSIosTouch *touch = [XSIosTouch sharedInstance];
|
||||
[touch Tap:i x:x y:y];
|
||||
});
|
||||
}
|
||||
|
||||
- (void) restart: (OnEndCallback) callback {
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
|
||||
#import "MyEventBus.h"
|
||||
#import "XSHackIos.h"
|
||||
#import "XSIosTouch.h"
|
||||
|
||||
|
||||
#define total_ad_click 3
|
||||
@ -267,34 +266,7 @@
|
||||
XSSaveAppInfo(appInfo, appInfoPath);
|
||||
|
||||
|
||||
// 1.截图 ocr识别弹窗,并关闭
|
||||
if([self getCurTime] - self->_lastOcrTime > 20) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@autoreleasepool {
|
||||
self->_lastOcrTime = [self getCurTime];
|
||||
UIImage *img = XSCcaptureScreen2();
|
||||
UIImage *jpg = [XSHelper png2jpg:img];
|
||||
if (jpg.CGImage) {
|
||||
UIImage *tempImg = [UIImage imageWithCGImage:jpg.CGImage];
|
||||
[XSHelper performOCROnImage:tempImg callback:^(NSString *text) {
|
||||
if (text == nil || [text isEqual:[NSNull null]] || [text length] <= 0) {
|
||||
NSLog(@"ocr text is null");
|
||||
} else {
|
||||
if ([text containsString:@"Apple ID Required"]) {
|
||||
XSIosTouch *touch = [[XSIosTouch alloc] init];
|
||||
[touch Tap:2 x:244 y:766];
|
||||
} else if([text containsString:@"This accessory may"]) {
|
||||
XSIosTouch *touch = [[XSIosTouch alloc] init];
|
||||
[touch Tap:2 x:382 y:746];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
jpg = nil;
|
||||
img = nil;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[[UIApplication sharedApplication] performSelectorOnMainThread:@selector(beginIgnoringInteractionEvents) withObject:nil waitUntilDone:YES];
|
||||
[[UIApplication sharedApplication] performSelectorOnMainThread:@selector(endIgnoringInteractionEvents) withObject:nil waitUntilDone:YES];
|
||||
@ -447,7 +419,6 @@
|
||||
int x = taskData->btnLoc->x * 2;
|
||||
int y = taskData->btnLoc->y;
|
||||
int ny = y * 2 + (self->_safeTop / 2) - 10;
|
||||
[[XSIosTouch sharedInstance] Tap:1 x:x y:ny];
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#import "MySimpleServer.h"
|
||||
#import "IosSystemCmd.h"
|
||||
#import "MyAdServer.h"
|
||||
#import "XSIosTouch.h"
|
||||
#import "XSHackIos.h"
|
||||
#import "MyAdTask2.h"
|
||||
#import "XUDPServer.h"
|
||||
@ -43,8 +42,6 @@ void startSimpleServer(void) {
|
||||
dispatch_async(serverQueue, ^{
|
||||
@autoreleasepool {
|
||||
// 初始化发送者ID
|
||||
XSInitGetSenderId();
|
||||
|
||||
// 启动日志
|
||||
pushIphoneLog(@"on start simple server!!!");
|
||||
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
//
|
||||
// XSIosTouch.h
|
||||
// nochange
|
||||
//
|
||||
// Created by mac on 2024/10/15.
|
||||
//
|
||||
|
||||
#ifndef XSIosTouch_h
|
||||
#define XSIosTouch_h
|
||||
|
||||
#import <IOKit/hid/IOHIDEvent.h>
|
||||
#import <IOKit/hid/IOHIDEventSystem.h>
|
||||
#import <IOKit/hid/IOHIDService.h>
|
||||
#import <IOKit/hid/IOHIDUserDevice.h>
|
||||
#import <IOKit/hid/IOHIDEventSystemClient.h>
|
||||
#import <IOKit/hid/IOHIDEventTypes.h>
|
||||
#import <IOKit/hid/IOHIDDisplay.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "IOHIDUsageTables.h"
|
||||
|
||||
void XSInitGetSenderId(void);
|
||||
|
||||
OBJC_EXTERN IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator);
|
||||
void IOHIDEventSetSenderID(IOHIDEventRef event, uint64_t senderID);
|
||||
void IOHIDEventSystemClientDispatchEvent(IOHIDEventSystemClientRef client, IOHIDEventRef event);
|
||||
// #define kIOHIDEventDigitizerSenderID 0xDEFACEDBEEFFECE5
|
||||
|
||||
uint64_t IOHIDEventGetSenderID(IOHIDEventRef event);
|
||||
uint64_t IOHIDEventGetSenderIDForEvent(IOHIDEventRef event);
|
||||
|
||||
enum {
|
||||
TOUCH_UP,
|
||||
TOUCH_DOWN,
|
||||
TOUCH_MOVE
|
||||
};
|
||||
|
||||
@interface XSIosTouch : NSObject
|
||||
+ (instancetype)sharedInstance;
|
||||
- (void) Down:(int) index x:(float)x y:(float) y;
|
||||
- (void) Move:(int) index x:(float)x y:(float) y;
|
||||
- (void) Up:(int) index x:(float)x y:(float) y;
|
||||
// - (void) End;
|
||||
- (void) Tap:(int) index x:(float)x y:(float)y;
|
||||
|
||||
- (void) KeyDown:(uint16_t)usage ;
|
||||
|
||||
- (void) KeyUp:(uint16_t)usage ;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* XSIosTouch_h */
|
||||
@ -1,503 +0,0 @@
|
||||
//
|
||||
// XSIosTouch.m
|
||||
// nochange
|
||||
//
|
||||
// Created by mac on 2024/10/15.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "XSIosTouch.h"
|
||||
#import "XSPhoneConfig.h"
|
||||
#import "XSHelper.h"
|
||||
|
||||
|
||||
// static var--------
|
||||
// touch event sender id
|
||||
static unsigned long long int _XSSenderID = 0x0;
|
||||
static IOHIDEventSystemClientRef _XSIoHIDEventSystemForSenderID = NULL;
|
||||
|
||||
// static var end--------
|
||||
|
||||
|
||||
/*
|
||||
Get the sender id and unregister itself.
|
||||
*/
|
||||
static void XSSetSenderIdCallback(void* target, void* refcon, IOHIDServiceRef service, IOHIDEventRef event)
|
||||
{
|
||||
NSLog(@"XSSetSenderIdCallback 1");
|
||||
if (IOHIDEventGetType(event) == kIOHIDEventTypeDigitizer){
|
||||
NSLog(@"XSSetSenderIdCallback 2");
|
||||
if (_XSSenderID == 0x0)
|
||||
{
|
||||
NSLog(@"XSSetSenderIdCallback 3");
|
||||
_XSSenderID = IOHIDEventGetSenderID(event);
|
||||
|
||||
NSInteger currentTime = [[NSDate date] timeIntervalSince1970];
|
||||
NSInteger timeSinceReboot = [NSProcessInfo processInfo].systemUptime;
|
||||
NSInteger rebootTime = currentTime - timeSinceReboot;
|
||||
XSPhoneConfig *config = [XSPhoneConfig sharedInstance];
|
||||
[config SetLastReboot:rebootTime];
|
||||
if (_XSSenderID > 0) {
|
||||
NSLog(@"XSSetSenderIdCallback 4");
|
||||
[config SetSenderId:_XSSenderID];
|
||||
}
|
||||
NSLog(@"com.zjx.springboard: sender id is: %qX", _XSSenderID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Start the callback for setting sender id
|
||||
*/
|
||||
static void XSStartSetSenderIDCallBack(void)
|
||||
{
|
||||
_XSIoHIDEventSystemForSenderID = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
|
||||
IOHIDEventSystemClientScheduleWithRunLoop(_XSIoHIDEventSystemForSenderID, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
IOHIDEventSystemClientRegisterEventCallback(_XSIoHIDEventSystemForSenderID, (IOHIDEventSystemClientEventCallback)XSSetSenderIdCallback, NULL, NULL);
|
||||
}
|
||||
void XSInitGetSenderId(void) {
|
||||
@try {
|
||||
NSInteger currentTime = [[NSDate date] timeIntervalSince1970];
|
||||
NSInteger timeSinceReboot = [NSProcessInfo processInfo].systemUptime;
|
||||
NSInteger thisRebootTime = currentTime - timeSinceReboot;
|
||||
|
||||
XSPhoneConfig *config = [XSPhoneConfig sharedInstance];
|
||||
NSInteger lastRebootTime = config.LastReboot;
|
||||
|
||||
if (labs(lastRebootTime - thisRebootTime) <= 3) {
|
||||
if (config.SenderId > 0) {
|
||||
_XSSenderID = config.SenderId;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_XSIoHIDEventSystemForSenderID) {
|
||||
XSStartSetSenderIDCallBack();
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSInteger retryCount = 0;
|
||||
while (retryCount < 10) {
|
||||
[NSThread sleepForTimeInterval:2.0f];
|
||||
|
||||
if (_XSIoHIDEventSystemForSenderID && _XSSenderID != 0x0) {
|
||||
IOHIDEventSystemClientUnregisterEventCallback(_XSIoHIDEventSystemForSenderID);
|
||||
IOHIDEventSystemClientUnscheduleWithRunLoop(_XSIoHIDEventSystemForSenderID, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
break;
|
||||
}
|
||||
|
||||
retryCount++;
|
||||
}
|
||||
|
||||
if (retryCount >= 10) {
|
||||
NSLog(@"Failed to get sender ID after maximum retries");
|
||||
}
|
||||
});
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error initializing sender ID: %@", exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@interface XSIosTouch() {
|
||||
@private
|
||||
CGFloat device_screen_width;
|
||||
CGFloat device_screen_height;
|
||||
IOHIDEventSystemClientRef ioSystemClient;
|
||||
dispatch_queue_t touchQueue;
|
||||
dispatch_semaphore_t eventSemaphore;
|
||||
NSTimeInterval lastEventTime;
|
||||
BOOL isProcessingEvent;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation XSIosTouch
|
||||
|
||||
+(instancetype)sharedInstance
|
||||
{
|
||||
static XSIosTouch* _sharedInstance = nil;
|
||||
static dispatch_once_t oncePredicate;
|
||||
dispatch_once (&oncePredicate, ^{
|
||||
_sharedInstance = [[XSIosTouch alloc] init];
|
||||
});
|
||||
return _sharedInstance;
|
||||
}
|
||||
|
||||
-(instancetype)init {
|
||||
if (self = [super init]) {
|
||||
@try {
|
||||
CGFloat screen_scale = [[UIScreen mainScreen] scale];
|
||||
self->device_screen_width = [UIScreen mainScreen].bounds.size.width * screen_scale;
|
||||
self->device_screen_height = [UIScreen mainScreen].bounds.size.height * screen_scale;
|
||||
|
||||
self->touchQueue = dispatch_queue_create("com.xsiostouch.queue", DISPATCH_QUEUE_SERIAL);
|
||||
self->ioSystemClient = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
|
||||
self->eventSemaphore = dispatch_semaphore_create(1);
|
||||
self->lastEventTime = 0;
|
||||
self->isProcessingEvent = NO;
|
||||
|
||||
return self;
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error initializing XSIosTouch: %@", exception);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
- (void)dealloc {
|
||||
if (self->ioSystemClient) {
|
||||
IOHIDEventSystemClientUnregisterEventCallback(self->ioSystemClient);
|
||||
CFRelease(self->ioSystemClient);
|
||||
self->ioSystemClient = NULL;
|
||||
}
|
||||
|
||||
if (_XSIoHIDEventSystemForSenderID) {
|
||||
IOHIDEventSystemClientUnregisterEventCallback(_XSIoHIDEventSystemForSenderID);
|
||||
CFRelease(_XSIoHIDEventSystemForSenderID);
|
||||
_XSIoHIDEventSystemForSenderID = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cleanupResources {
|
||||
@synchronized(self) {
|
||||
if (self->ioSystemClient) {
|
||||
IOHIDEventSystemClientUnregisterEventCallback(self->ioSystemClient);
|
||||
CFRelease(self->ioSystemClient);
|
||||
self->ioSystemClient = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
- (BOOL)checkSystemStatus {
|
||||
// 检查系统状态,防止过度负载
|
||||
if (self->isProcessingEvent) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
|
||||
if (currentTime - self->lastEventTime < 0.016) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)resetEventSystem {
|
||||
@synchronized(self) {
|
||||
if (self->ioSystemClient) {
|
||||
IOHIDEventSystemClientUnregisterEventCallback(self->ioSystemClient);
|
||||
CFRelease(self->ioSystemClient);
|
||||
self->ioSystemClient = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
|
||||
}
|
||||
self->isProcessingEvent = NO;
|
||||
}
|
||||
}
|
||||
- (void)handleEventSystemFailure {
|
||||
static int failureCount = 0;
|
||||
|
||||
@synchronized(self) {
|
||||
failureCount++;
|
||||
if (failureCount >= 3) {
|
||||
[self resetEventSystem];
|
||||
failureCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// device screen size
|
||||
- (AbsoluteTime) getAbsoluteTime {
|
||||
uint64_t machAbsoluteTime = mach_absolute_time();
|
||||
AbsoluteTime timeStamp;
|
||||
timeStamp.hi = (UInt32)(machAbsoluteTime >> 32);
|
||||
timeStamp.lo = (UInt32)(machAbsoluteTime);
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (IOHIDEventRef)generateChildEvent:(int)index type:(int)type x:(float)x y:(float)y {
|
||||
@try {
|
||||
if (x < 0 || y < 0 || index < 0) {
|
||||
NSLog(@"Invalid parameters for child event");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AbsoluteTime timeStamp = [self getAbsoluteTime];
|
||||
uint32_t isTouch = (type == TOUCH_UP) ? 0 : 1;
|
||||
IOHIDDigitizerEventMask eventMask = 0;
|
||||
|
||||
// 设置事件掩码
|
||||
if (type != TOUCH_UP && type != TOUCH_DOWN) {
|
||||
eventMask |= kIOHIDDigitizerEventPosition;
|
||||
}
|
||||
if (type == TOUCH_UP || type == TOUCH_DOWN) {
|
||||
eventMask |= (kIOHIDDigitizerEventTouch | kIOHIDDigitizerEventRange);
|
||||
}
|
||||
|
||||
// 坐标归一化
|
||||
double dx = (self->device_screen_width > 0) ? (x / self->device_screen_width) : 0;
|
||||
double dy = (self->device_screen_height > 0) ? (y / self->device_screen_height) : 0;
|
||||
|
||||
// 确保坐标在有效范围内
|
||||
dx = fmin(fmax(dx, 0.0), 1.0);
|
||||
dy = fmin(fmax(dy, 0.0), 1.0);
|
||||
|
||||
float x_rounded = XSRoundToDecimal(dx, 4);
|
||||
float y_rounded = XSRoundToDecimal(dy, 4);
|
||||
|
||||
IOHIDEventRef child = IOHIDEventCreateDigitizerFingerEvent(
|
||||
kCFAllocatorDefault,
|
||||
timeStamp,
|
||||
index,
|
||||
3,
|
||||
eventMask,
|
||||
x_rounded,
|
||||
y_rounded,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
isTouch,
|
||||
isTouch,
|
||||
0
|
||||
);
|
||||
|
||||
if (!child) {
|
||||
NSLog(@"Failed to create child event");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IOHIDEventSetFloatValue(child, kIOHIDEventFieldDigitizerMajorRadius, 0.04f);
|
||||
IOHIDEventSetFloatValue(child, kIOHIDEventFieldDigitizerMinorRadius, 0.04f);
|
||||
if (!child) {
|
||||
[self handleEventSystemFailure];
|
||||
return NULL;
|
||||
}
|
||||
return child;
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error generating child event: %@", exception);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Get the child event of touching down.
|
||||
index: index of the finger
|
||||
x: coordinate x of the screen (before conversion)
|
||||
y: coordinate y of the screen (before conversion)
|
||||
*/
|
||||
- (IOHIDEventRef) generateChildEventTouchDown:(int) index x:(float)x y:(float) y
|
||||
{
|
||||
return [self generateChildEvent:index type:TOUCH_DOWN x:x y:y];
|
||||
}
|
||||
|
||||
/*
|
||||
Get the child event of touching move.
|
||||
index: index of the finger
|
||||
x: coordinate x of the screen (before conversion)
|
||||
y: coordinate y of the screen (before conversion)
|
||||
*/
|
||||
- (IOHIDEventRef) generateChildEventTouchMove:(int) index x:(float)x y:(float) y
|
||||
{
|
||||
return [self generateChildEvent:index type:TOUCH_MOVE x:x y:y];
|
||||
}
|
||||
|
||||
/*
|
||||
Get the child event of touching up.
|
||||
index: index of the finger
|
||||
x: coordinate x of the screen (before conversion)
|
||||
y: coordinate y of the screen (before conversion)
|
||||
*/
|
||||
- (IOHIDEventRef) generateChildEventTouchUp:(int) index x:(float)x y:(float) y
|
||||
{
|
||||
return [self generateChildEvent:index type:TOUCH_UP x:x y:y];
|
||||
}
|
||||
|
||||
- (IOHIDEventRef) generateParentEvent {
|
||||
// generate a parent event
|
||||
AbsoluteTime timeStamp = [self getAbsoluteTime];
|
||||
//IOHIDEventRef parent = IOHIDEventCreateDigitizerEvent(kCFAllocatorDefault, timeStamp, 3, 99, 1, 4, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0);
|
||||
|
||||
IOHIDEventRef parent = IOHIDEventCreateDigitizerEvent(kCFAllocatorDefault, //allocator
|
||||
timeStamp, // timeStamp
|
||||
kIOHIDDigitizerTransducerTypeHand, //IOHIDDigitizerTransducerType
|
||||
1, // uint32_t index
|
||||
0, // uint32_t identity
|
||||
kIOHIDDigitizerEventTouch, // uint32_t eventMask
|
||||
0, // uint32_t buttonMask
|
||||
0.0, // IOHIDFloat x
|
||||
0.0, // IOHIDFloat y
|
||||
0.0, // IOHIDFloat z
|
||||
0.0, // IOHIDFloat tipPressure
|
||||
0.0, //IOHIDFloat barrelPressure
|
||||
false, // boolean range
|
||||
true, // boolean touch
|
||||
0// IOOptionBits options
|
||||
);
|
||||
|
||||
IOHIDEventSetIntegerValue(parent , 0xb0019, 1); //set flags of parent event flags: 0x20001 -> 0xa0001
|
||||
IOHIDEventSetIntegerValue(parent , 0x4, 1); //set flags of parent event flags: 0xa0001 -> 0xa0011
|
||||
//kIOHIDEventFieldDigitizerIsDisplayIntegrated
|
||||
//IOHIDEventSetIntegerValue(parent, kIOHIDEventFieldDigitizerIrregularity, 1);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
- (UIWindow*) getKeyWindow {
|
||||
for (UIWindow *window in [UIApplication sharedApplication].windows) {
|
||||
if (window.isKeyWindow) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Post the parent event
|
||||
*/
|
||||
- (void)postIOHIDEvent:(IOHIDEventRef)_parent {
|
||||
if (!_parent) return;
|
||||
|
||||
// 控制事件发送频率
|
||||
NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
|
||||
if (currentTime - self->lastEventTime < 0.016) { // 限制最高约60fps
|
||||
usleep(((0.016 - (currentTime - self->lastEventTime)) * 1000000));
|
||||
}
|
||||
|
||||
dispatch_semaphore_wait(self->eventSemaphore, DISPATCH_TIME_FOREVER);
|
||||
@try {
|
||||
if (!self->ioSystemClient) {
|
||||
self->ioSystemClient = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
|
||||
}
|
||||
|
||||
if (_XSSenderID > 0) {
|
||||
IOHIDEventSetSenderID(_parent, _XSSenderID);
|
||||
}
|
||||
|
||||
if (self->ioSystemClient) {
|
||||
IOHIDEventSystemClientDispatchEvent(self->ioSystemClient, _parent);
|
||||
}
|
||||
|
||||
self->lastEventTime = [[NSDate date] timeIntervalSince1970];
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error posting IOHIDEvent: %@", exception);
|
||||
} @finally {
|
||||
dispatch_semaphore_signal(self->eventSemaphore);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) Down:(int) index x:(float)x y:(float) y {
|
||||
@autoreleasepool {
|
||||
IOHIDEventRef _parent = [self generateParentEvent];
|
||||
IOHIDEventRef event = [self generateChildEventTouchDown:index x:x y:y];
|
||||
IOHIDEventAppendEvent(_parent, event);
|
||||
[self End: _parent];
|
||||
}
|
||||
}
|
||||
- (void) Move:(int) index x:(float)x y:(float) y {
|
||||
@autoreleasepool {
|
||||
IOHIDEventRef _parent = [self generateParentEvent];
|
||||
IOHIDEventRef event = [self generateChildEventTouchMove:index x:x y:y];
|
||||
IOHIDEventAppendEvent(_parent, event);
|
||||
[self End:_parent];
|
||||
}
|
||||
}
|
||||
- (void) Up:(int) index x:(float)x y:(float) y {
|
||||
@autoreleasepool {
|
||||
IOHIDEventRef _parent = [self generateParentEvent];
|
||||
IOHIDEventRef event = [self generateChildEventTouchUp:index x:x y:y];
|
||||
IOHIDEventAppendEvent(_parent, event);
|
||||
[self End: _parent];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)Tap:(int)index x:(float)x y:(float)y {
|
||||
if (index <= 0 || x < 0 || y < 0) {
|
||||
NSLog(@"Invalid tap parameters");
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->isProcessingEvent) {
|
||||
NSLog(@"Already processing event, skipping tap");
|
||||
return;
|
||||
}
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_async(self->touchQueue, ^{
|
||||
__strong typeof(weakSelf) strongSelf = weakSelf;
|
||||
@try {
|
||||
strongSelf->isProcessingEvent = YES;
|
||||
|
||||
// 添加延迟以防止事件过于密集
|
||||
NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
|
||||
if (currentTime - strongSelf->lastEventTime < 0.05) {
|
||||
usleep(50000); // 50ms最小间隔
|
||||
}
|
||||
|
||||
[strongSelf Down:index x:x y:y];
|
||||
usleep(50000); // 增加按下和抬起之间的延迟
|
||||
[strongSelf Up:index x:x y:y];
|
||||
|
||||
strongSelf->lastEventTime = [[NSDate date] timeIntervalSince1970];
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error performing tap: %@", exception);
|
||||
} @finally {
|
||||
strongSelf->isProcessingEvent = NO;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)End:(IOHIDEventRef)_parent {
|
||||
if (!_parent) {
|
||||
NSLog(@"Invalid parent event");
|
||||
return;
|
||||
}
|
||||
|
||||
@try {
|
||||
IOHIDEventSetIntegerValue(_parent, kIOHIDEventFieldDigitizerTiltX, kIOHIDDigitizerTransducerTypeHand);
|
||||
IOHIDEventSetIntegerValue(_parent, kIOHIDEventFieldDigitizerTiltY, 1);
|
||||
IOHIDEventSetIntegerValue(_parent, kIOHIDEventFieldDigitizerAltitude, 1);
|
||||
|
||||
[self postIOHIDEvent:_parent];
|
||||
CFRelease(_parent);
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Error ending event: %@", exception);
|
||||
if (_parent) {
|
||||
CFRelease(_parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) Keyboard:(uint16_t)usage down:(Boolean)down {
|
||||
static IOHIDEventSystemClientRef client = nil;
|
||||
if (client == nil) {
|
||||
client = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
|
||||
}
|
||||
AbsoluteTime timeStamp = [self getAbsoluteTime];
|
||||
IOHIDEventRef event = IOHIDEventCreateKeyboardEvent(
|
||||
kCFAllocatorDefault,
|
||||
timeStamp,
|
||||
kHIDPage_KeyboardOrKeypad,
|
||||
usage,
|
||||
down,
|
||||
0
|
||||
);
|
||||
IOHIDEventSetSenderID(event, _XSSenderID);
|
||||
IOHIDEventSystemClientDispatchEvent(client, event);
|
||||
CFRelease(event);
|
||||
//CFRelease(client);
|
||||
|
||||
}
|
||||
|
||||
- (void) KeyDown:(uint16_t)usage {
|
||||
[self Keyboard:usage down:true];
|
||||
}
|
||||
|
||||
- (void) KeyUp:(uint16_t)usage {
|
||||
[self Keyboard:usage down:false];
|
||||
}
|
||||
|
||||
@end
|
||||
BIN
packages/251030-nt.deb
Normal file
BIN
packages/251030-nt.deb
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user