GSSendEvent - 注入触摸事件 iOS

问题描述 投票:0回答:2

我想在iPhone中注入触摸事件。我通过网络套接字获取触摸事件的坐标。

GSSendEvent
似乎是不错的选择。但是,它需要
GSEventRecord
作为输入之一。

有人知道如何准备吗

GSEventRecord
?我根据一些示例准备了它,但应用程序在
GSSendEvent
调用后崩溃了。

感谢任何帮助。

-(void) handleMouseEventAtPoint:(CGPoint) point
{
static mach_port_t port_;

// structure of touch GSEvent
struct GSTouchEvent {
    GSEventRecord record;
    GSHandInfo    handInfo;
} ;

struct GSTouchEvent *touchEvent = (struct GSTouchEvent *) malloc(sizeof(struct GSTouchEvent));

bzero(touchEvent, sizeof(touchEvent));

// set up GSEvent
touchEvent->record.type = kGSEventHand;
touchEvent->record.windowLocation = point;
touchEvent->record.timestamp = GSCurrentEventTimestamp();
touchEvent->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
touchEvent->handInfo.type = getHandInfoType(0, 1);
touchEvent->handInfo.pathInfosCount = 1;
bzero(&touchEvent->handInfo.pathInfos[0], sizeof(GSPathInfo));
touchEvent->handInfo.pathInfos[0].pathIndex     = 1;
touchEvent->handInfo.pathInfos[0].pathIdentity  = 2;
touchEvent->handInfo.pathInfos[0].pathProximity = 1 ? 0x03 : 0x00;
touchEvent->handInfo.pathInfos[0].pathLocation  = point;

port_ = GSGetPurpleSystemEventPort();

GSSendEvent((GSEventRecord*)touchEvent ,port_);


}
static GSHandInfoType getHandInfoType(int touch_before, int touch_now){
if (!touch_before) {
    return (GSHandInfoType) kGSHandInfoType2TouchDown;
}
if (touch_now) {
    return (GSHandInfoType) kGSHandInfoType2TouchChange;
}
return (GSHandInfoType) kGSHandInfoType2TouchFinal;
}
ios objective-c touch iphone-privateapi
2个回答
6
投票

仅在 iOS 6 上测试

您实际上走在正确的道路上。问题是您必须弄清楚应该为这些变量分配什么值。

首先需要导入GraphicsServices.h。然后,您可以使用从如何在IOS 5及以上版本中找到最前面的应用程序的紫色端口?.

获得的端口尝试以下代码。

我不是 iOS 专家,Apple 也没有提供任何文档,所以我无法解释太多这里发生的事情。 (它恰好对我来说效果很好。)

无论如何,您可以使用 xcode 调试模式来使用它,看看幕后发生了什么。

struct GSTouchEvent * touchEvent = (struct GSTouchEvent*) &gsTouchEvent;
bzero(touchEvent, sizeof(touchEvent));
touchEvent->record.type = kGSEventHand;
touchEvent->record.subtype = kGSEventSubTypeUnknown;
touchEvent->record.location = point;
touchEvent->record.windowLocation = point;
touchEvent->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
touchEvent->record.timestamp = GSCurrentEventTimestamp();
touchEvent->record.window = winRef;
touchEvent->record.senderPID = 919;
bzero(&touchEvent->handInfo, sizeof(GSHandInfo));
bzero(&touchEvent->handInfo.pathInfos[0], sizeof(GSPathInfo));
GSHandInfo touchEventHandInfo;
touchEventHandInfo._0x5C = 0;
touchEventHandInfo.deltaX = 0;
touchEventHandInfo.deltaY = 0;
touchEventHandInfo.height = 0;
touchEventHandInfo.width = 0;
touchEvent->handInfo = touchEventHandInfo;
touchEvent->handInfo.type = handInfoType;
touchEvent->handInfo.deltaX = 1;
touchEvent->handInfo.deltaY = 1;
touchEvent->handInfo.pathInfosCount = 0;
touchEvent->handInfo.pathInfos[0].pathIndex = 1;
touchEvent->handInfo.pathInfos[0].pathIdentity = 2;
touchEvent->handInfo.pathInfos[0].pathProximity = (handInfoType == kGSHandInfoTypeTouchDown || handInfoType == kGSHandInfoTypeTouchDragged || handInfoType == kGSHandInfoTypeTouchMoved) ? 0x03: 0x00;
touchEvent->handInfo.x52 = 1;
touchEvent->handInfo.pathInfos[0].pathLocation = point;
touchEvent->handInfo.pathInfos[0].pathWindow = winRef;
GSEventRecord* record = (GSEventRecord*) touchEvent;
record->timestamp = GSCurrentEventTimestamp();
GSSendEvent(record, port);

要使用此代码,您必须多次调用它。对于一键点击,有触摸、触摸拖动和触摸向上。

另请注意,当触摸向上时,pathProximity 为 0。

据我记得,winRef 并不重要。

希望这有帮助。

编辑:从 Bugivore 的评论来看,问题是:

我通过malloc分配touchEvent的方式是错误的。应该按照 EntryLevelDev 显示的那样完成 - “static uint8_t handJob[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];”


3
投票

EntryLevelDev 的答案是正确的,但有些值并不是那么重要。我从其他地方得到了下面的代码,并做了一些尝试和错误,这是我的代码(适用于最新的 ios6)。

现在有人在为 IOS7 做这个工作吗?我无法让它工作。请参阅我的帖子:随着 GraphicsServices 中的 GSCopyPurpleNamedPort(appId) 在 IOS7 中已弃用,替代方法是什么?

static int prev_click = 0;

if (!click && !prev_click)
{
    //which should never enter
    NSLog(@"***error, postHandEvent cancel");
    return;
}

CGPoint location = CGPointMake(x, y);

struct GSTouchEvent {
    GSEventRecord record;
    GSHandInfo    handInfo;
} * event = (struct GSTouchEvent*) &touchEvent;
bzero(touchEvent, sizeof(touchEvent));

event->record.type = kGSEventHand;
event->record.windowLocation = location;
event->record.timestamp = GSCurrentEventTimestamp();
//NSLog(@"Timestamp GSCurrentEventTimestamp: %llu",GSCurrentEventTimestamp());
event->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
event->handInfo.type = getHandInfoType(prev_click, click);

//must have the following line
event->handInfo.x52 = 1;

//below line is for ios4
//event->handInfo.pathInfosCount = 1;


bzero(&event->handInfo.pathInfos[0], sizeof(GSPathInfo));
event->handInfo.pathInfos[0].pathIndex     = 2;
//following 2 lines, they are by default
event->handInfo.pathInfos[0].pathMajorRadius = 1.0;
event->handInfo.pathInfos[0].pathPressure = 1.0;

//event->handInfo.pathInfos[0].pathIdentity  = 2;
event->handInfo.pathInfos[0].pathProximity = click ? 0x03 : 0x00;
//event->handInfo.pathInfos[0].pathProximity = action;
event->handInfo.pathInfos[0].pathLocation  = location;

// send GSEvent 
GSEventRecord *event1 = (GSEventRecord*) event;
sendGSEvent(event1);
© www.soinside.com 2019 - 2024. All rights reserved.