void end_screen(char *message, int exit_val) { int footer_rows_was_one = 0; if(panicking()) return; if(FOOTER_ROWS(ps_global) == 1){ footer_rows_was_one++; FOOTER_ROWS(ps_global) = 3; mark_status_unknown(); } flush_status_messages(exit_val ? 0 : 1); blank_keymenu(_lines - 2, 0); if(message){ StartInverse(); PutLine0(_lines - 2, 0, message); } EndInverse(); MoveCursor(_lines - 1, 0); mswin_showcaret(F_ON(F_SHOW_CURSOR, ps_global)); if(footer_rows_was_one){ FOOTER_ROWS(ps_global) = 1; mark_status_unknown(); } }
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"); }
/* * pipe_callback - handle pine-specific pipe setup like child * signal handler and possibly any display stuff * BUG: this function should probably be in a "alpine/pipe.c" */ void pipe_callback(PIPE_S *syspipe, int flags, void *data) { #ifdef _WINDOWS bitmap_t bitmap; #endif if(flags & OSB_PRE_OPEN) { dprint((5, "Opening pipe: (%s%s%s%s%s%s)\n", (syspipe->mode & PIPE_WRITE) ? "W":"", (syspipe->mode & PIPE_READ) ? "R":"", (syspipe->mode & PIPE_NOSHELL) ? "N":"", (syspipe->mode & PIPE_PROT) ? "P":"", (syspipe->mode & PIPE_USER) ? "U":"", (syspipe->mode & PIPE_RESET) ? "T":"")); #ifdef _WINDOWS q_status_message(SM_ORDER, 0, 0, "Waiting for called program to finish..."); flush_status_messages(1); setbitmap(bitmap); draw_keymenu(&pipe_cancel_keymenu, bitmap, ps_global->ttyo->screen_cols, 1-FOOTER_ROWS(ps_global), 0, FirstMenu); #else /* UNIX */ if(!(syspipe->mode & (PIPE_WRITE | PIPE_READ)) && !(syspipe->mode & PIPE_SILENT)) { flush_status_messages(0); /* just clean up display */ ClearScreen(); fflush(stdout); } if(syspipe->mode & PIPE_RESET) ttyfix(0); #ifdef SIGCHLD /* * Prepare for demise of child. Use SIGCHLD if it's available so * we can do useful things, like keep the IMAP stream alive, while * we're waiting on the child. The handler may have been changed by * something in the composer, in particular, by an alt_editor call. * So we need to re-set it to child_signal and then set it back * when we're done. */ child_signalled = child_jump = 0; syspipe->chld = signal(SIGCHLD, child_signal); #endif #endif /* UNIX */ } else if(flags & OSB_POST_OPEN) { #ifdef _WINDOWS clearfooter(ps_global); ps_global->mangled_footer = 1; if((int) data == -2) q_status_message1(SM_ORDER, 2, 3, "Ignoring completion of %s", syspipe->command); #else /* UNIX */ if(!(syspipe->mode & (PIPE_WRITE | PIPE_READ)) && !(syspipe->mode & PIPE_SILENT)) { ClearScreen(); ps_global->mangled_screen = 1; } if(syspipe->mode & PIPE_RESET) ttyfix(1); #ifdef SIGCHLD (void) signal(SIGCHLD, SIG_DFL); #endif #endif /* UNIX */ } else if(flags & OSB_PRE_CLOSE) { #ifdef SIGCHLD /* * this is here so close_system_pipe so it has something * to do while we're waiting on the other end of the * pipe to complete. When we're in the background for * a shell, the the side effect is pinging */ RETSIGTYPE (*alarm_sig)(); int old_cue = F_ON(F_SHOW_DELAY_CUE, ps_global); /* * remember the current SIGALRM handler, and make sure it's * installed when we're finished just in case the longjmp * out of the SIGCHLD handler caused sleep() to lose it. * Don't pay any attention to that man behind the curtain. */ alarm_sig = signal(SIGALRM, SIG_IGN); (void) F_SET(F_SHOW_DELAY_CUE, ps_global, 0); ps_global->noshow_timeout = 1; while(!child_signalled) { /* wake up and prod server */ if(!(syspipe->mode & PIPE_NONEWMAIL)) new_mail(0, 2, (syspipe->mode & PIPE_RESET) ? NM_NONE : NM_DEFER_SORT); if(!child_signalled) { if(setjmp(child_state) == 0) { child_jump = 1; /* prepare to wake up */ sleep(600); /* give it 5mins to happend */ } else our_sigunblock(SIGCHLD); } child_jump = 0; } ps_global->noshow_timeout = 0; F_SET(F_SHOW_DELAY_CUE, ps_global, old_cue); (void) signal(SIGALRM, alarm_sig); (void) signal(SIGCHLD, syspipe->chld); #endif } else if(flags & OSB_POST_CLOSE) { if(syspipe->mode & PIPE_RESET) /* restore our tty modes */ ttyfix(1); if(!(syspipe->mode & (PIPE_WRITE | PIPE_READ | PIPE_SILENT))) { ClearScreen(); /* No I/O to forked child */ ps_global->mangled_screen = 1; } } }