Exemple #1
0
void
osx_launch_special_handling(MCAP_CMD_S *mc_cmd, char *image_file)
{
    CFStringRef str_ref = NULL;
    CFURLRef url_ref = NULL;
    LSLaunchFSRefSpec launch_spec;
    FSRef app_ref, file_ref;
    static EXEC_EVENT_DATA_S event_data;

    install_app_launch_cb((void *)&event_data);
    if((str_ref = CFStringCreateWithCString(NULL, mc_cmd->command,
					kCFStringEncodingASCII)) == NULL)
      return;
    if((url_ref = CFURLCreateWithString(NULL, str_ref, NULL)) == NULL)
      return;
    if(CFURLGetFSRef(url_ref, &app_ref) == false)
      return;
    if(FSPathMakeRef((unsigned char *)image_file,
		     &file_ref, NULL) != noErr)
      return;
    launch_spec.appRef = &app_ref;
    launch_spec.numDocs = 1;
    launch_spec.itemRefs = &file_ref;
    launch_spec.passThruParams = NULL;
    launch_spec.launchFlags = kLSLaunchDontAddToRecents | kLSLaunchNoParams
      | kLSLaunchAsync | kLSLaunchNewInstance;
    /* would want to use this if we ever did true event handling */
    launch_spec.asyncRefCon = 0;

    if(LSOpenFromRefSpec( &launch_spec, NULL) == noErr){
	/*
	 * Here's the strategy:  we want to be able to just launch
	 * the app and then just delete the temp file, but that
	 * doesn't work because the called app needs the temp file
	 * at least until it's finished loading.  Being that there's
	 * no way to tell when the app has finished loading, we wait
	 * until the program has exited, which is the safest thing to
	 * do and is what we do for windows.  Since we haven't totally
	 * embraced event handling at this point, we must do the waiting
	 * synchronously.  We allow for a keystroke to stop waiting, and
	 * just delete the temp file.
	 *   Ideally, we would launch the app, and keep running, checking
	 * the events until the process terminates, and then delete the
	 * temp file.  In this method, we would delete the temp file
	 * at close time if the app was still running.
	 */
	int ch;
	OSStatus rne_rv;
	EventTargetRef target;
	EventRef out_event;
	EventTypeSpec event_types[2] = {
	    {kEventClassApplication, kEventAppTerminated},
	    {kEventClassApplication, kEventAppLaunchNotification}};

	q_status_message(SM_ORDER, 0, 4,
	  "Waiting for program to finish, or press a key to stop waiting...");
	flush_status_messages(1);
	target = GetEventDispatcherTarget();
	event_data.done = 0;
	event_data.set_pid = 0;
	while(!event_data.done){
	    if((rne_rv = ReceiveNextEvent(2, event_types, 1,
					  true, &out_event)) == noErr){
		SendEventToEventTarget(out_event, target);
		ReleaseEvent(out_event);
	    }
	    else if(rne_rv == eventLoopTimedOutErr){
		ch = read_char(1);
		if(ch)
		  event_data.done = 1;
	    }
	    else if(rne_rv == eventLoopQuitErr)
	      event_data.done = 1;
	}
	our_unlink(image_file);
    }
    q_status_message(SM_ORDER, 0, 4, "VIEWER command completed");
}
Exemple #2
0
void pybase::OpenEditor()
{
    if(!module) return;
    const char *mname = PyModule_GetFilename(module);
    if(!mname) {
        PyErr_Clear();
        return;
    }

    char fname[1024];
    strcpy(fname,mname);

    // replacing .pyc or .pyo for source file name
    char *dt = strrchr(fname,'.');
    if(dt && !strncmp(dt,".py",2)) strcpy(dt,".py");

    // this should open the editor....
#if FLEXT_OS == FLEXT_OS_WIN
    int err = (int)ShellExecute(NULL,"edit",fname,NULL,NULL,SW_SHOW);
    if(err == SE_ERR_NOASSOC) {
        // no association found - try notepad
        err = (int)ShellExecute(NULL,NULL,"notepad.exe",fname,NULL,SW_SHOW);
    }
    else if(err == ERROR_FILE_NOT_FOUND || err == SE_ERR_FNF)
        post("py/pyext - File not %s found",fname);
    else if(err <= 32)
        post("py/pyext - Unknown error opening %s",fname);
       
#elif FLEXT_OS == FLEXT_OS_MAC
    FSRef ref;
    OSStatus err = FSPathMakeRef((unsigned char *)fname,&ref,NULL);
    if(err)
        post("py/pyext - Error interpreting path %s",fname);
    else {
        FSRef editor;
        err = LSGetApplicationForItem(&ref,kLSRolesEditor,&editor,NULL);
        if(err) {
            // Can't find associated application... try Textedit
            err = FSPathMakeRef((unsigned char *)"/Applications/TextEdit.app",&editor,NULL);
            if(err)
                post("py/pyext - Can't find Textedit application");
        }
        
        if(!err) {
            LSLaunchFSRefSpec lspec;
            lspec.appRef = &editor;
            lspec.numDocs = 1;
            lspec.itemRefs = &ref;
            lspec.passThruParams = NULL;
            lspec.launchFlags = kLSLaunchDefaults;
            lspec.asyncRefCon = NULL;
            err = LSOpenFromRefSpec(&lspec,NULL);
            if(err)
                post("py/pyext - Couldn't launch editor");
        }
    }
#else
    // thanks to Tim Blechmann

    char *editor = getenv("EDITOR");

    if(!editor) { // || !strcmp(editor, "/usr/bin/nano") || !strcmp(editor, "/usr/bin/pico") || !strcmp(editor, "/usr/bin/vi")) {
        // no environment variable or console text editor found ... use idle instead (should have come with Python)
        editor = "idle";
    }

    pid_t child = fork();  
    if(!child) {
        char cmd[80];
        strcpy(cmd,editor);
        strcat(cmd," ");
        strcat(cmd,fname);
        execl("/bin/sh", "sh", "-c", cmd, (char *) NULL);
    }
#endif
}