2013-04-23 13 views
8

Desidero inserire l'evento tocco in iPhone. Ottengo le coordinate dell'evento touch tramite la presa di rete. GSSendEvent sembra essere una buona scelta. Tuttavia, ha bisogno di GSEventRecord come uno degli input.GSSendEvent - Inject Touch Event iOS

Qualcuno sa come preparare GSEventRecord? L'ho preparato in base ad alcuni esempi, ma l'app si arresta in modo anomalo dopo la chiamata a GSSendEvent.

Apprezzare qualsiasi aiuto.

-(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; 
} 

risposta

6

Solo testato su iOS 6

Vi sono in realtà sulla strada giusta. Il problema è che devi capire quali valori dovresti assegnare a queste variabili.

Prima di tutto, è necessario importare GraphicsServices.h. Quindi, puoi provare il seguente codice con la porta che puoi ottenere da How to find the purple port for the front most application in IOS 5 and above?.

Non sono un esperto iOS e Apple non fornisce documentazione, quindi non posso spiegare molto su cosa sta succedendo qui. (Succede di funzionare bene per me.)

In ogni caso, è possibile giocare con esso utilizzando la modalità di debug di xcode per vedere cosa succede sotto il cofano.

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

Per utilizzare questo codice, è necessario chiamarlo più volte. Per un tocco, ci sono touch-down, tocca-trascina e poi ritocca.

Si noti inoltre che pathProximity è 0 quando il tocco è attivo.

Per quanto mi ricordo, winRef non ha importanza.

Spero che questo aiuti.

Edit: Dal commento di Bugivore, il problema è:

Il modo in cui ho assegnata TouchEvent tramite malloc era sbagliato. Dovrebbe essere fatto come EntryLevelDev ha mostrato - "statico uint8_t handJob [sizeof (GSEventRecord) + sizeof (GSHandInfo) + sizeof (GSPathInfo)];"

+0

Ciao ELD - Grazie per l'aiuto. Ho provato e si blocca in objc_msgSend. – Jailbroken

+0

ok, per favore controlla il mio progetto su github ... https: //github.com/entryleveldev/touchy – pt2121

+0

Ha funzionato molto bene! Grazie mille. – Jailbroken

3

La risposta da EntryLevelDev è corretta, ma parte del valore non è così importante. Ho ricevuto i codici qui sotto da qualche altra parte e ho fatto alcuni tentativi ed errori, ecco i miei codici (ha funzionato fino all'ultimo ios6).

E chiunque sta lavorando su questo per IOS7 ora? Non riuscivo a farlo funzionare. vedi il mio post qui: 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); 
+0

È grandioso. Buono a sapersi. Thx – pt2121

+0

Hai mai funzionato su iOS7? –

+1

No, non con Graphicsservices. Stiamo utilizzando un altro modo per simulare il tocco dell'utente difficile. – user2485972