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