0

我编写代码通过 GSEvent 向我的应用程序发送触摸事件,通过 GSCopyPurpleSystemEventPort() 获取 mach_port_t。

ApplicationDidFinishLaunch:选项完成后启动发送功能。应用程序是 UIControlView 应用程序。

代码如下:

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!");
    }
}

但是越狱ipad2(iOS5.01)上的应用启动,没有任何点击结果,如果点击事件完成,debug.log会在那里。

谁能告诉我我有什么想念的?

4

1 回答 1

0

我在其他地方看到过这段代码(我认为它是在一个将鼠标点击转换为 iPhone/iPad 水龙头的应用程序上)。这里的问题不是代码或端口,而是您发送的事件结构。这是 iOS 3.0 的 GSevent 结构,而不是 iOS 5.0。它不仅在结构上,而且在值和标签上都发生了变化。我建议接收 UIEvents,将它们翻译成 GSEvents 并查看它们的内容。

于 2012-04-30T07:40:23.767 回答