0

I code to send a touch event to my app by GSEvent,get mach_port_t by GSCopyPurpleSystemEventPort().

the sending function was launched after the ApplicationDidFinishLaunch:option have completed.the app is UIControlView app.

code as follow:

void handleMouseEventAtPoint(CGPoint point, int buttons)
{
    // NOTE: Must store button state for comparision, port for
    //       mouse dragging and button up
    static int buttons_;
    static mach_port_t port_;

    int diff = buttons_ ^ buttons;
    bool twas = ((buttons_ & 0x1) != 0);
    bool tis = ((buttons & 0x1) != 0);
    buttons_ = buttons;

    // Round point values to prevent subpixel coordinates
    point.x = roundf(point.x);
    point.y = roundf(point.y);

    // Check for mouse button events
    mach_port_t purple;

    if ((diff & 0x10) != 0) {
        // Simulate Headset button press
        struct GSEventRecord record;

        memset(&record, 0, sizeof(record));

        record.type = (buttons & 0x4) != 0 ?
        kGSEventHeadsetButtonDown :
        kGSEventHeadsetButtonUp;

        record.timestamp = GSCurrentEventTimestamp();
        FixRecord(&record);
        GSSendSystemEvent(&record);
    }

    if ((diff & buttonThree) != 0) {
        // Simulate Home button press
        struct GSEventRecord record;

        memset(&record, 0, sizeof(record));

        record.type = (buttons & buttonThree) != 0 ?
        kGSEventMenuButtonDown :
        kGSEventMenuButtonUp;

        record.timestamp = GSCurrentEventTimestamp();
        FixRecord(&record);
        GSSendSystemEvent(&record);
    }

    if ((diff & buttonTwo) != 0) 
    {
        // Simulate Sleep/Wake button press
        struct GSEventRecord record;

        memset(&record, 0, sizeof(record));

        record.type = (buttons & buttonTwo) != 0 ?
        kGSEventLockButtonDown :
        kGSEventLockButtonUp;

        record.timestamp = GSCurrentEventTimestamp();
        FixRecord(&record);
        GSSendSystemEvent(&record);
    }

    if (twas != tis || tis) {
        // Main (left button) state changed, or was dragged
        struct {
            struct GSEventRecord record;
            struct 
            {
                struct GSEventRecordInfo info;
                struct GSPathInfo path;
            } data;
        } event;

        memset(&event, 0, sizeof(event));

        event.record.type = kGSEventHand;
        event.record.windowLocation = point;
        event.record.timestamp = GSCurrentEventTimestamp();
        event.record.infoSize = sizeof(event.data);

        event.data.info.handInfo.type = twas == tis ?
        kGSHandInfoTypeTouchDragged :
        tis ?
        kGSHandInfoTypeTouchDown :
        kGSHandInfoTypeTouchUp;

        event.data.info.handInfo._0x44 = 0x1;
        event.data.info.handInfo._0x48 = tis ? 0x1 : 0x0;

        event.data.info.pathPositions = 1;

        event.data.path.pathIndex = 0x01;
        event.data.path.pathIdentity = 0x02;
        event.data.path.pathProximity = tis ? 0x03 : 0x00;
        event.data.path.pathLocation = event.record.windowLocation;

        if (twas != tis && tis) 
        {
            // Button down and was not down before
            port_ = 0;

            CAWindowServer *server;

            server = [CAWindowServer serverIfRunning];
            char svrptrstr [255];
            sprintf(svrptrstr, "%p", server);

            NSLog(@"One!");

            if (server = [CAWindowServer serverIfRunning]) 
                //if (true)
            {
                NSLog(@"Two!");
                //NSArray *displays([server displays]);
                NSArray *displays = [server displays];
                if (displays != nil && [displays count] != 0)
                {
                    NSLog(@"Three!");
                    //CAWindowServer *display;
                    if (CAWindowServerDisplay *display = [displays objectAtIndex:0])
                    {
                        NSLog(@"Four!");
                        port_ = [display clientPortAtPosition:point];
                    }
                }
            }

            if (port_ == 0) 
            {
                // Is SpringBoard
                if (purple == 0)
                {
                    purple = GSGetPurpleSystemEventPort();
                    port_ = purple;

                }
            }
        }

        FixRecord(&event.record);

        GSSendEvent(&event.record, port_);
        NSLog(@"Event sent!");
        //GSSendSystemEvent(&event.record);
        //GSSendEvent(&event.record, purple);
    }

    if (purple != 0 && PurpleAllocated)
    {
        mach_port_deallocate(mach_task_self(), purple);
        NSLog(@"Deallocated mach_port!");
    }
}

but the app launch on the jailbreak ipad2(iOS5.01),there is no any click result,if click event was done,the debug.log would be there.

who can tell me what i have miss?

Hawk-Eye
  • 400
  • 1
  • 7
  • 23
AngelWing
  • 1
  • 1
  • 2
  • Any progress on this further? was u able to send touch event for ios 5.0 onwards? If yes then please let us know too. – user2197966 Apr 02 '13 at 07:24

1 Answers1

0

I've seen this code somewhere else (I think it was on an app that translated mouse clicks to iPhone/iPad taps). The problem here is not the code or the port, but the event structure you are sending. This is the GSevent structure for iOS 3.0, not for iOS 5.0. It has changed, not only in structure but in values and tags. I suggest receiving UIEvents, translating them into GSEvents and looking at their content.

Jorge Aguirre
  • 2,787
  • 3
  • 20
  • 27
  • Is there infomation about the GSEvent structure for iOS 5.0 online?If it's yes,could you give me the URL? – AngelWing May 02 '12 at 08:29
  • No, online there is not. The furthest you can go is KennyTM's private API library. I recommend that you receive every UIEvent and translate it to a GSEvent. Then look closely at the values you receive, make a similar structure and send it. – Jorge Aguirre May 07 '12 at 08:38
  • I override the touchesBegan:withEvent:,and translate it to GSEvent to force,look at the structure,but i think this infomation is wrong.Maybe couldn't translate it to GSEvent to force. – AngelWing May 08 '12 at 09:14
  • How do you translate it to a UIEvent? You should use the instance method -(GSEventRef)_gsEvent; and then translate it to a GSEventRecord, then look at the values. – Jorge Aguirre May 09 '12 at 11:51
  • I translate it as that you said,and i found the propertie value is the same to GSEvent.h.It's still inviald.Could you have any other suggestion.I want to go hell. – AngelWing May 16 '12 at 02:15
  • What results do you obtain? What are the values you obtain for the GSEvent structure? Post them in your answer, that might help. – Jorge Aguirre May 16 '12 at 10:15