Use GSEvent to send touch event,but it's invalid

感情迁移 提交于 2019-12-13 12:46:58

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/10274405/use-gsevent-to-send-touch-event-but-its-invalid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!