Hi there,

I'm writing my first mobilesubstrate extension. I used a template that I found here to start me off on the right foot, and I have successfully hooked into Springboard.

I want this extension to be able to send fake touch and keyboard events to Springboard, to be interpreted by the OS or by the currently running app. Here's my code for doing the mouse event handling (this is mostly from Saurik's Veency):

Code:
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!");
	}
}
I call this function like this in Springboard's applicationDidFinishLaunching:

Code:
handleMouseEventAtPoint(CGPointMake(42, 460), 0x1);
For whatever reason, I get the NSLog() messages in the device's Console, but the event isn't sent (I think it's supposed to touch the phone icon). Am I missing something?

Any and all help would be greatly greatly appreciated!