GSSendEvent – 注入触摸事件iOS

我想在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 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)];”

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

现在有人在为IOS7工作吗? 我无法让它发挥作用。 在这里看到我的post: 在IOS7中不推荐使用GraphicsServices中的GSCopyPurpleNamedPort(appId),有什么替代方法?

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