GSSendEvent - Inject Touch Event iOS

。_饼干妹妹 提交于 2019-11-27 21:36:50
pt2121

Only tested on iOS 6

You are actually on the right track. The problem is you have to figure out what values you should assign to these variables.

First of all, you need to import GraphicsServices.h. Then, you can try the following code with the port which you can get from How to find the purple port for the front most application in IOS 5 and above?.

I am not an iOS expert and Apple doesn't provide any documentation so I can't explain much what's going on here. (It happens to work fine for me.)

Anyway, you can play with it using xcode debug mode to see what happens under the hood.

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

To use this code, you have to call it multiple times. For one tap, there are touch-down, touch-drag and then touch-up.

Also note that pathProximity is 0 when touch is up.

As far as I remember, the winRef doesn't matter.

Hope this helps.

Edit: From Bugivore's comment, the problem is:

The way I allocated touchEvent via malloc was wrong. It should be done as EntryLevelDev showed - "static uint8_t handJob[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];"

user2485972

Answer from EntryLevelDev is correct, but some of the value is not so important. I got the below codes from somewhere else and have done some try and errors, here is my codes(worked for till latested ios6).

And is anyone working on this for IOS7 now? I could not get it to work. see my post here: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);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!