Request programatic control

Discussion in 'Parallels Desktop for Mac' started by farcrafter, May 11, 2006.

  1. farcrafter

    farcrafter Bit poster

    Messages:
    3
    Hi,

    It would be really nice to control Parallels from scripts and other programs. Here is some sample code to do it with CFMessagePorts which would only take a few minutes to put in. Then just publish a header with the supported messages. Call ParallelsListen from the main thread once. inContext will be passed to ParallelsHandle. ParallelsHandle will be called when a message is sent.

    Just add messages for the things that are buttons or menu items in the interface, and a few for status information.


    enum {
    kParallelsMessages = 100 ,

    kParallelsActivate , /* -> CFString in property list */
    kParallelsDeactivate ,

    kParallelsFullScreenOn ,
    kParallelsFullScreenOff ,
    kParallelsFullScreenIsOn , /* <- UInt8 */
    };


    CFDataRef ParallelsHandle( CFMessagePortRef inPort , SInt32 inMessage , CFDataRef inData , void *inContext ) {
    CFDataRef result = NULL;
    UInt8 byte = 0 , return_byte = 0;
    CFPropertyListRef return_list = NULL;

    switch ( inMessage ) {
    case kParallelsActivate: /*ensure specified image (inData is path) is running in full screen*/ break;
    case kParallelsDeactivate: /*pause running machine and uncapture screen but do not revert to window*/ break;

    case kParallelsFullScreenOn: /*run full screen if not already*/ break;
    case kParallelsFullScreenOff: /*run in window if full screen*/ break;
    case kParallelsFullScreenIsOn: byte = /*is running full screen*/; return_byte = 1; break;

    /*support other messages too*/
    /* machine image: get/set full path of current machine */
    /* machine state: no machine, loaded, running, paused */
    /* acceleration level: no machine, 1, 2, 3, ... */
    }

    if ( return_byte ) {
    result = CFDataCreate( NULL , &byte , 1 );
    }

    if ( return_list ) {
    result = CFPropertyListCreateXMLData( NULL , return_list );
    CFRelease( return_list );
    }

    return result;
    }


    void ParallelsListen( void *inContext ) {
    CFMessagePortContext context = { 0 , inContext };
    CFRunLoopRef loop = CFRunLoopGetCurrent();
    CFStringRef name = loop ? CFStringCreateWithFormat( NULL , NULL , CFSTR( "com.parallels.workstation.%d" ) , getpid() ) : NULL;
    CFMessagePortRef port = name ? CFMessagePortCreateLocal( NULL , name , ParallelsHandle , &context , NULL ) : NULL;
    CFRunLoopSourceRef source = port ? CFMessagePortCreateRunLoopSource( NULL , port , 0 ) : NULL;

    if ( source ) CFRunLoopAddSource( loop , source , kCFRunLoopDefaultMode );
    if ( name ) CFRelease( name );
    if ( port ) CFRelease( port );
    if ( source ) CFRelease( source );
    }


    Then you can also create a simple command line tool that sends messages to support and apple script or shell script. Or leave it up to coders to directly interact with parallels.

    Thanks
    Eric
     

Share This Page