/*---------------------------------------------------------------------- Set or reset what needs to be set when coming out of pico to run an alternate editor. Args: come_back -- If come_back is 0 we're going out of our environment to set up for an external editor. If come_back is 1 we're coming back into pine. ----------------------------------------------------------------------*/ int ttyfix(int come_back) { #if defined(DEBUG) && (!defined(DOS) || defined(_WINDOWS)) if(debugfile) fflush(debugfile); #endif if(come_back) { #ifdef OS2 enter_text_mode(NULL); #endif init_screen(); init_tty_driver(ps_global); init_keyboard(F_ON(F_USE_FK,ps_global)); #ifdef OS2 dont_interrupt(); #endif fix_windsize(ps_global); } else { EndInverse(); end_keyboard(F_ON(F_USE_FK,ps_global)); end_tty_driver(ps_global); end_screen(NULL, 0); #ifdef OS2 interrupt_ok(); #endif } return(0); }
/*---------------------------------------------------------------------- This checks whether or not a character (UNIX) is ready to be read, or it times out. Args: time_out -- number of seconds before it will timeout Result: Returns a NO_OP_IDLE or a NO_OP_COMMAND if the timeout expires before input is available, or a KEY_RESIZE if a resize event occurs, or READY_TO_READ if input is available before the timeout. ----*/ UCS check_for_timeout(int time_out) { UCS res = NO_OP_COMMAND; fflush(stdout); #if defined(SIGWINCH) && defined(TIOCGWINSZ) if(!winch_occured){ if(setjmp(winch_state) != 0){ winch_occured = 1; ready_for_winch = 0; /* * Need to unblock signal after longjmp from handler, because * signal is normally unblocked upon routine exit from the handler. */ our_sigunblock(SIGWINCH); } else ready_for_winch = 1; } if(winch_occured){ winch_occured = ready_for_winch = 0; fix_windsize(ps_global); return(KEY_RESIZE); } #endif /* SIGWINCH */ switch(res = input_ready(time_out)){ case BAIL_OUT: read_bail(); /* non-tragic exit */ /* NO RETURN */ case PANIC_NOW: panic1("Select error: %s\n", error_description(errno)); /* NO RETURN */ case READ_INTR: res = NO_OP_COMMAND; /* fall through */ case NO_OP_IDLE: case NO_OP_COMMAND: case READY_TO_READ: #if defined(SIGWINCH) && defined(TIOCGWINSZ) ready_for_winch = 0; #endif return(res); } /* not reachable */ return(res); }
int pine_simple_ttgetc(int (*fi)(int), void (*fv)(void)) { int ch; #if defined(SIGWINCH) && defined(TIOCGWINSZ) if(!winch_occured){ if(setjmp(winch_state) != 0){ winch_occured = 1; ready_for_winch = 0; /* * Need to unblock signal after longjmp from handler, because * signal is normally unblocked upon routine exit from the handler. */ our_sigunblock(SIGWINCH); } else ready_for_winch = 1; } if(winch_occured){ winch_occured = ready_for_winch = 0; fix_windsize(ps_global); return(KEY_RESIZE); } #endif /* SIGWINCH */ ch = simple_ttgetc(fi, fv); #if defined(SIGWINCH) && defined(TIOCGWINSZ) ready_for_winch = 0; #endif return(ch); }
/*---------------------------------------------------------------------- Suspend Pine. Reset tty and suspend. Suspend is finished when this returns Args: The pine structure Result: Execution suspended for a while. Screen will need redrawing after this is done. Instead of the usual handling of ^Z by catching a signal, we actually read the ^Z and then clean up the tty driver, then kill ourself to stop, and pick up where we left off when execution resumes. ----------------------------------------------------------------------*/ UCS do_suspend(void) { struct pine *pine = ps_global; time_t now; UCS retval; #if defined(DOS) || defined(OS2) int result, orig_cols, orig_rows; #else int isremote; #endif #ifdef DOS static char *shell = NULL; #define STD_SHELL "COMMAND.COM" #else #ifdef OS2 static char *shell = NULL; #define STD_SHELL "CMD.EXE" #endif #endif if(!have_job_control()) { bogus_command(ctrl('Z'), F_ON(F_USE_FK, pine) ? "F1" : "?"); return(NO_OP_COMMAND); } if(F_OFF(F_CAN_SUSPEND, pine)) { q_status_message(SM_ORDER | SM_DING, 3, 3, _("Alpine suspension not enabled - see help text")); return(NO_OP_COMMAND); } #ifdef _WINDOWS mswin_minimize(); return(NO_OP_COMMAND); #else isremote = (ps_global->mail_stream && ps_global->mail_stream->mailbox && (*ps_global->mail_stream->mailbox == '{' || (*ps_global->mail_stream->mailbox == '*' && *(ps_global->mail_stream->mailbox + 1) == '{'))); now = time((time_t *)0); dprint((1, "\n\n --- %s - SUSPEND ---- %s", isremote ? "REMOTE" : "LOCAL", ctime(&now))); ttyfix(0); #if defined(DOS) || defined(OS2) suspend_notice("exit"); if (!shell) { char *p; if (!((shell = getenv("SHELL")) || (shell = getenv("COMSPEC")))) shell = STD_SHELL; shell = cpystr(shell); /* copy in free storage */ for(p = shell; (p = strchr(p, '/')); p++) *p = '\\'; } result = system(shell); #else if(F_ON(F_SUSPEND_SPAWNS, ps_global)) { PIPE_S *syspipe; if((syspipe = open_system_pipe(NULL, NULL, NULL, PIPE_USER|PIPE_RESET, 0, pipe_callback, pipe_report_error)) != NULL) { suspend_notice("exit"); #ifndef SIGCHLD if(isremote) suspend_warning(); #endif (void) close_system_pipe(&syspipe, NULL, pipe_callback); } } else { suspend_notice("fg"); if(isremote) suspend_warning(); stop_process(); } #endif /* DOS */ now = time((time_t *)0); dprint((1, "\n\n ---- RETURN FROM SUSPEND ---- %s", ctime(&now))); ttyfix(1); #if defined(DOS) || defined(OS2) orig_cols = pine->ttyo->screen_cols; orig_rows = pine->ttyo->screen_rows; #endif fix_windsize(pine); #if defined(DOS) || defined(OS2) if(orig_cols != pine->ttyo->screen_cols || orig_rows != pine->ttyo->screen_rows) retval = KEY_RESIZE; else #endif retval = ctrl('L');; #if defined(DOS) || defined(OS2) if(result == -1) q_status_message1(SM_ORDER | SM_DING, 3, 4, _("Error loading \"%s\""), shell); #endif if(isremote && !pine_mail_ping(ps_global->mail_stream)) q_status_message(SM_ORDER | SM_DING, 4, 9, _("Suspended for too long, IMAP connection broken")); return(retval); #endif /* !_WINDOWS */ }