【问题标题】:GSSendEvent - Inject Touch Event iOSGSSendEvent - 注入触摸事件 iOS
【发布时间】:2013-04-16 03:36:52
【问题描述】:

我想在 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 api touch private iphone-privateapi


    【解决方案1】:

    仅在 iOS 6 上测试

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

    首先,您需要导入 GraphicsServices.h。然后,您可以使用可以从How to find the purple port for the front most application in IOS 5 and above? 获取的端口尝试以下代码。

    我不是 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)];”

    【讨论】:

    • 嗨,ELD - 感谢您的帮助。我试过了,它在 objc_msgSend 中崩溃了。
    • 好的,请在github上查看我的项目...github.com/entryleveldev/touchy
    • 工作得很好!非常感谢。
    • 我通过 malloc 分配 touchEvent 的方式是错误的。应该像 EntryLevelDev 所示那样完成 - “static uint8_t handJob[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];”
    • 但是如何模拟多点触控事件呢?
    【解决方案2】:

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

    现在有人在为 IOS7 做这个吗?我无法让它工作。在这里查看我的帖子:With GSCopyPurpleNamedPort(appId) in GraphicsServices deprecated in IOS7, what is the alternative approach?

    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);
    

    【讨论】:

    • 太好了。很高兴知道。谢谢
    • 不,不是图形服务。我们正在使用另一种方式来模拟用户触摸强硬。
    • 嗨 user2485972,你能分享一些关于你的 ios 7 touch injection 的信息吗?
    • @user2485972 As is it possible for system wise touch on IOS7, the answer is no for me -- 你是说你不知道如何在 iOS 7 中模拟系统范围的触摸事件?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 2015-02-06
    相关资源
    最近更新 更多