/* ARGSUSED */ int savebuffers(int f, int n) { if (anycb(f) == ABORT) return (ABORT); return (TRUE); }
/* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ int quit (int f, int n) { int s; if (f != FALSE /* Argument forces it */ || anycb () == FALSE /* All buffers clean */ || (s = mlyesno ("Modified buffers exist. Leave anyway")) == TRUE) { vttidy (); exit (0); } mlwrite (""); return (s); }
/* ARGSUSED */ int quit(int f, int n) { int s; if ((s = anycb(FALSE)) == ABORT) return (ABORT); if (s == FALSE || eyesno("Modified buffers exist; really exit") == TRUE) { vttidy(); closetags(); exit(GOOD); } return (TRUE); }
/* ARGSUSED */ int quit(int f, int n) { int s; if ((s = anycb(FALSE)) == ABORT) return (ABORT); if (s == FIOERR || s == UERROR) return (FALSE); if (s == FALSE || eyesno("Modified buffers exist; really exit") == TRUE) { vttidy(); exit(0); } return (TRUE); }
/* * abort_composer - ask the question here, then go quit or * return FALSE */ int abort_composer(int f, int n) { char *result; result = ""; Pmaster->arm_winch_cleanup++; if(Pmaster->canceltest){ if(((Pmaster->pine_flags & MDHDRONLY) && !any_header_changes()) || (result = (*Pmaster->canceltest)(redraw_pico_for_callback))){ pico_all_done = COMP_CANCEL; emlwrite(result, NULL); Pmaster->arm_winch_cleanup--; return(TRUE); } else{ /* TRANSLATORS: The user typed the Cancel command and was asked to confirm that. Instead they canceled the cancel command. */ emlwrite(_("Cancel Cancelled"), NULL); curwp->w_flag |= WFMODE; /* and modeline so we */ sgarbk = TRUE; /* redraw the keymenu */ pclear(term.t_nrow-1, term.t_nrow); Pmaster->arm_winch_cleanup--; return(FALSE); } } else switch(mlyesno_utf8(Pmaster->headents ? _("Cancel message (answering \"Yes\" will abandon your mail message)") : (anycb() == FALSE) ? _("Cancel Edit (and abandon changes)") : _("Cancel Edit"), FALSE)){ case TRUE: pico_all_done = COMP_CANCEL; return(TRUE); case ABORT: emlwrite(_("\007Cancel Cancelled"), NULL); break; default: mlerase(); } return(FALSE); }
/* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ globle int edquit( void *theEnv, int f, int n) { register int s; if (f != FALSE /* Argument forces it. */ || anycb() == FALSE /* All buffers clean. */ /* User says it's OK. */ || (s=mlyesno(theEnv,"Modified Buffers! Quit")) == TRUE) { vttidy(); full_cleanup(theEnv); return(EXIT); } return (s); }
/* ARGSUSED */ int quit(int f, int n) { int s; if ((s = anycb(FALSE)) == ABORT) return (ABORT); if (s == FALSE || eyesno("Modified buffers exist; really exit") == TRUE) { vttidy(); #ifdef SYSCLEANUP SYSCLEANUP; #endif /* SYSCLEANUP */ exit(GOOD); } return (TRUE); }
/* * This is the general command execution routine. It handles the fake binding * of all the keys to "self-insert". It also clears out the "thisflag" word, * and arranges to move it to the "lastflag", so that the next command can * look at it. Return the status of command. */ int execute(int c, int f, int n) { int status; fn_t execfunc; /* if the keystroke is a bound function...do it */ execfunc = getbind(c); if (execfunc != NULL) { thisflag = 0; status = (*execfunc) (f, n); lastflag = thisflag; return status; } /* * If a space was typed, fill column is defined, the argument is non- * negative, wrap mode is enabled, and we are now past fill column, * and we are not read-only, perform word wrap. */ if (c == ' ' && (curwp->w_bufp->b_mode & MDWRAP) && fillcol > 0 && n >= 0 && getccol(FALSE) > fillcol && (curwp->w_bufp->b_mode & MDVIEW) == FALSE) execute(META | SPEC | 'W', FALSE, 1); #if PKCODE if ((c >= 0x20 && c <= 0x7E) /* Self inserting. */ #if IBMPC || (c >= 0x80 && c <= 0xFE)) { #else #if VMS || BSD || USG /* 8BIT P.K. */ || (c >= 0xA0 && c <= 0xFFFF)) { #else ) { #endif #endif #else if ((c >= 0x20 && c <= 0xFF)) { /* Self inserting. */ #endif if (n <= 0) { /* Fenceposts. */ lastflag = 0; return n < 0 ? FALSE : TRUE; } thisflag = 0; /* For the future. */ /* if we are in overwrite mode, not at eol, and next char is not a tab or we are at a tab stop, delete a char forword */ if (curwp->w_bufp->b_mode & MDOVER && curwp->w_doto < curwp->w_dotp->l_used && (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' || (curwp->w_doto) % 8 == 7)) ldelchar(1, FALSE); /* do the appropriate insertion */ if (c == '}' && (curbp->b_mode & MDCMOD) != 0) status = insbrace(n, c); else if (c == '#' && (curbp->b_mode & MDCMOD) != 0) status = inspound(); else status = linsert(n, c); #if CFENCE /* check for CMODE fence matching */ if ((c == '}' || c == ')' || c == ']') && (curbp->b_mode & MDCMOD) != 0) fmatch(c); #endif /* check auto-save mode */ if (curbp->b_mode & MDASAVE) if (--gacount == 0) { /* and save the file if needed */ upscreen(FALSE, 0); filesave(FALSE, 0); gacount = gasave; } lastflag = thisflag; return status; } TTbeep(); mlwrite("(Key not bound)"); /* complain */ lastflag = 0; /* Fake last flags. */ return FALSE; } /* * Fancy quit command, as implemented by Norm. If the any buffer has * changed do a write on that buffer and exit emacs, otherwise simply exit. */ int quickexit(int f, int n) { struct buffer *bp; /* scanning pointer to buffers */ struct buffer *oldcb; /* original current buffer */ int status; oldcb = curbp; /* save in case we fail */ bp = bheadp; while (bp != NULL) { if ((bp->b_flag & BFCHG) != 0 /* Changed. */ && (bp->b_flag & BFTRUNC) == 0 /* Not truncated P.K. */ && (bp->b_flag & BFINVS) == 0) { /* Real. */ curbp = bp; /* make that buffer cur */ mlwrite("(Saving %s)", bp->b_fname); #if PKCODE #else mlwrite("\n"); #endif if ((status = filesave(f, n)) != TRUE) { curbp = oldcb; /* restore curbp */ return status; } } bp = bp->b_bufp; /* on to the next buffer */ } quit(f, n); /* conditionally quit */ return TRUE; } static void emergencyexit(int signr) { quickexit(FALSE, 0); quit(TRUE, 0); } /* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ int quit(int f, int n) { int s; if (f != FALSE /* Argument forces it. */ || anycb() == FALSE /* All buffers clean. */ /* User says it's OK. */ || (s = mlyesno("Modified buffers exist. Leave anyway")) == TRUE) { #if (FILOCK && BSD) || SVR4 if (lockrel() != TRUE) { TTputc('\n'); TTputc('\r'); TTclose(); TTkclose(); exit(1); } #endif vttidy(); if (f) exit(n); else exit(GOOD); } mlwrite(""); return s; } /* * Begin a keyboard macro. * Error if not at the top level in keyboard processing. Set up variables and * return. */ int ctlxlp(int f, int n) { if (kbdmode != STOP) { mlwrite("%%Macro already active"); return FALSE; } mlwrite("(Start macro)"); kbdptr = &kbdm[0]; kbdend = kbdptr; kbdmode = RECORD; return TRUE; } /* * End keyboard macro. Check for the same limit conditions as the above * routine. Set up the variables and return to the caller. */ int ctlxrp(int f, int n) { if (kbdmode == STOP) { mlwrite("%%Macro not active"); return FALSE; } if (kbdmode == RECORD) { mlwrite("(End macro)"); kbdmode = STOP; } return TRUE; } /* * Execute a macro. * The command argument is the number of times to loop. Quit as soon as a * command gets an error. Return TRUE if all ok, else FALSE. */ int ctlxe(int f, int n) { if (kbdmode != STOP) { mlwrite("%%Macro already active"); return FALSE; } if (n <= 0) return TRUE; kbdrep = n; /* remember how many times to execute */ kbdmode = PLAY; /* start us in play mode */ kbdptr = &kbdm[0]; /* at the beginning */ return TRUE; } /* * Abort. * Beep the beeper. Kill off any keyboard macro, etc., that is in progress. * Sometimes called as a routine, to do general aborting of stuff. */ int ctrlg(int f, int n) { TTbeep(); kbdmode = STOP; mlwrite("(Aborted)"); return ABORT; }
/* * packbuf - will pack up the main buffer in the buffer provided * to be returned to the program that called pico. * if need be, allocate memory for the new message. * will also free the memory associated with the editor * buffer, by calling zotedit. */ int packbuf(char **buf, int *blen, int lcrlf) /* EOLs are local or CRLF */ { register int i = 0; register LINE *lp; register int retval = 0; register char *bufp; register char *eobuf; if(anycb() != FALSE){ lp = lforw(curbp->b_linep); do{ /* how many chars? */ i += llength(lp); /* * add extra for new lines to be inserted later */ i += 2; lp = lforw(lp); } while(lp != curbp->b_linep); if(i > *blen){ /* new buffer ? */ /* * don't forget to add one for the null terminator!!! */ if((bufp = (char *)malloc((i+1)*sizeof(char))) == NULL){ zotedit(); /* bag it! */ return(COMP_FAILED); } free(*buf); *buf = bufp; *blen = i; } else{ bufp = *buf; } eobuf = bufp + *blen; lp = lforw(curbp->b_linep); /* First line. */ do { for (i = 0; i < llength(lp); i++){ /* copy into buffer */ if((bufp+1) < eobuf){ *bufp++ = (lp->l_text[i].c & 0xFF); } else{ /* * the idea is to malloc enough space for the new * buffer... */ *bufp = '\0'; zotedit(); return(BUF_CHANGED|COMP_FAILED); } } if(lcrlf){ *bufp++ = '\n'; /* EOLs use local convention */ } else{ *bufp++ = 0x0D; /* EOLs use net standard */ *bufp++ = 0x0A; } lp = lforw(lp); } while (lp != curbp->b_linep); if(lcrlf) *--bufp = '\0'; else *bufp = '\0'; retval = BUF_CHANGED; } zotedit(); return(retval); }
/* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ int wquit(int f, int n) { register int s; if(Pmaster){ char *result = NULL; int ret; /* First, make sure there are no outstanding problems */ if(AttachError()){ emlwrite(_("\007Problem with attachments! Fix errors or delete attachments."), NULL); return(FALSE); } #ifdef SPELLER if(Pmaster->always_spell_check) if(spell(0, 0) == -1) sleep(3); /* problem, show error */ #endif /* * if we're not in header, show some of it as we verify sending... */ display_for_send(); packheader(); Pmaster->arm_winch_cleanup++; if((!(Pmaster->pine_flags & MDHDRONLY) || any_header_changes()) && (ret = (*Pmaster->exittest)(Pmaster->headents, redraw_pico_for_callback, Pmaster->allow_flowed_text, &result))){ Pmaster->arm_winch_cleanup--; if(ret == -1){ pico_all_done = COMP_CANCEL; } else{ if(sgarbf) update(); lchange(WFHARD); /* set update flags... */ curwp->w_flag |= WFMODE; /* and modeline so we */ sgarbk = TRUE; /* redraw the keymenu */ pclear(term.t_nrow-2, term.t_nrow); } if(result && *result) emlwrite(result, NULL); } else{ Pmaster->arm_winch_cleanup--; pico_all_done = COMP_EXIT; return(TRUE); } } else{ if (f != FALSE /* Argument forces it. */ || anycb() == FALSE /* All buffers clean. */ /* User says it's OK. */ /* TRANSLATORS: buffer is the in-memory copy of a file */ || (s=mlyesno_utf8(_("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES)"), -1)) == FALSE) { vttidy(); #if defined(USE_TERMCAP) || defined(USE_TERMINFO) || defined(VMS) kbdestroy(kbesc); #endif exit(0); } if(s == TRUE){ if(filewrite(0,1) == TRUE) wquit(1, 0); } else if(s == ABORT){ emlwrite(_("Exit cancelled"), NULL); if(term.t_mrow == 0) curwp->w_flag |= WFHARD; /* cause bottom 3 lines to paint */ } return(s); } return(FALSE); }
/* * pico - the main routine for Pine's composer. * */ int pico(PICO *pm) { UCS c; register int f; register int n; char bname[NBUFN]; /* buffer name of file to read */ extern struct on_display ods; int checkpointcnt = 0, input = 0; int ret; char chkptfile[NLINE]; #ifdef _WINDOWS int cursor_shown; #endif Pmaster = pm; gmode = MDWRAP; gmode |= pm->pine_flags; /* high 4 bits rsv'd for pine */ alt_speller = pm->alt_spell; pico_all_done = 0; km_popped = 0; if(!vtinit()) /* Init Displays. */ return(COMP_CANCEL); strncpy(bname, "main", sizeof(bname)); /* default buffer name */ bname[sizeof(bname)-1] = '\0'; edinit(bname); /* Buffers, windows. */ if(InitMailHeader(pm)) /* init mail header structure */ gmode &= ~(P_BODY | P_HEADEND); /* flip off special header stuff */ /* setup to process commands */ lastflag = 0; /* Fake last flags. */ curbp->b_mode |= gmode; /* and set default modes*/ if(Pmaster->pine_anchor) pico_anchor = utf8_to_ucs4_cpystr(Pmaster->pine_anchor); else pico_anchor = NULL; if(Pmaster->quote_str) glo_quote_str = utf8_to_ucs4_cpystr(Pmaster->quote_str); else glo_quote_str = NULL; if(Pmaster->wordseps) glo_wordseps = ucs4_cpystr(Pmaster->wordseps); else glo_wordseps = NULL; bindtokey(DEL, (gmode & P_DELRUBS) ? forwdel : backdel); if(pm->msgtext) breplace(pm->msgtext); #ifdef _WINDOWS cursor_shown = mswin_showcaret(1); /* turn on for main window */ mswin_allowpaste(MSWIN_PASTE_FULL); mswin_setscrollcallback (pico_scroll_callback); #endif /* prepare for checkpointing */ chkptfile[0] = '\0'; chkptinit((*Pmaster->ckptdir)(chkptfile, sizeof(chkptfile)), sizeof(chkptfile)); if(gmode & P_CHKPTNOW) writeout(chkptfile, TRUE); pico_all_done = setjmp(finstate); /* jump out of HUP handler ? */ if(gmode & MDALTNOW){ while(!pico_all_done){ if(((gmode & P_BODY) || !Pmaster->headents) && alt_editor(0, 1) < 0) break; /* if problem, drop into pico */ if(Pmaster->headents){ update(); /* paint screen, n' start editing... */ HeaderEditor((gmode & (P_HEADEND | P_BODY)) ? 2 : 0, 0); gmode |= P_BODY; /* make sure we enter alt ed next */ } else pico_all_done = COMP_EXIT; } } else if(!pico_all_done){ if(gmode & P_BODY){ /* begin editing the header? */ ArrangeHeader(); /* line up pointers */ /* * Move to the offset pine asked us to move to. * Perhaps we should be checking to see if this is * a reasonable number before moving. */ if(Pmaster && Pmaster->edit_offset) forwchar(FALSE, Pmaster->edit_offset); } else{ update(); /* paint screen, */ HeaderEditor((gmode & P_HEADEND) ? 2 : 0, 0); } } while(1){ if(pico_all_done){ #ifdef _WINDOWS if(!cursor_shown) mswin_showcaret(0); mswin_allowpaste(MSWIN_PASTE_DISABLE); mswin_setscrollcallback (NULL); #endif ret = anycb() ? BUF_CHANGED : 0; switch(pico_all_done){ /* prepare for/handle final events */ case COMP_EXIT : /* already confirmed */ packheader(); if(Pmaster && (Pmaster->strip_ws_before_send || Pmaster->allow_flowed_text)) cleanwhitespace(); ret |= COMP_EXIT; break; case COMP_CANCEL : /* also already confirmed */ packheader(); ret = COMP_CANCEL; break; case COMP_GOTHUP: /* * pack up and let caller know that we've received a SIGHUP */ if(ComposerEditing) /* expand addr if needed */ call_builder(&headents[ods.cur_e], NULL, NULL); packheader(); ret |= COMP_GOTHUP; break; case COMP_SUSPEND : default: /* safest if internal error */ /* * If we're in the headers mark the current header line * with start_here bit so caller knows where to reset. * Also set the edit_offset, which is either the offset * into this header line or the offset into the body. * Packheader will adjust edit_offset for multi-line * headers. */ if(ComposerEditing){ /* in the headers */ headents[ods.cur_e].start_here = 1; Pmaster->edit_offset = ods.p_ind; } else{ register LINE *clp; register long offset; for(clp = lforw(curbp->b_linep), offset = 0L; clp != curwp->w_dotp; clp = lforw(clp)) offset += (llength(clp) + 1); Pmaster->edit_offset = offset + curwp->w_doto; } packheader(); ret |= COMP_SUSPEND; break; } if(pico_anchor) fs_give((void **) &pico_anchor); if(glo_quote_str) fs_give((void **) &glo_quote_str); if(glo_wordseps) fs_give((void **) &glo_wordseps); vttidy(); /* clean up tty modes */ zotdisplay(); /* blast display buffers */ zotedit(); our_unlink(chkptfile); Pmaster = NULL; /* blat global */ return(ret); } if(km_popped){ km_popped--; if(km_popped == 0) /* cause bottom three lines to be repainted */ curwp->w_flag |= WFHARD; } if(km_popped){ /* temporarily change to cause menu to be painted */ term.t_mrow = 2; curwp->w_ntrows -= 2; curwp->w_flag |= WFMODE; movecursor(term.t_nrow-2, 0); /* clear status line, too */ peeol(); } update(); /* Fix up the screen */ if(km_popped){ term.t_mrow = 0; curwp->w_ntrows += 2; } #ifdef MOUSE #ifdef EX_MOUSE /* New mouse function for real mouse text seletion. */ register_mfunc(mouse_in_pico, 2, 0, term.t_nrow - (term.t_mrow+1), term.t_ncol); #else mouse_in_content(KEY_MOUSE, -1, -1, -1, 0); register_mfunc(mouse_in_content, 2, 0, term.t_nrow - (term.t_mrow + 1), term.t_ncol); #endif #endif #ifdef _WINDOWS mswin_setdndcallback (composer_file_drop); mswin_mousetrackcallback(pico_cursor); #endif c = GetKey(); if (term.t_nrow < 6 && c != NODATA){ (*term.t_beep)(); emlwrite(_("Please make the screen bigger."), NULL); continue; } #ifdef MOUSE #ifdef EX_MOUSE clear_mfunc(mouse_in_pico); #else clear_mfunc(mouse_in_content); #endif #endif #ifdef _WINDOWS mswin_cleardndcallback (); mswin_mousetrackcallback(NULL); #endif if(c == NODATA || time_to_check()){ /* new mail ? */ if((*Pmaster->newmail)(c == NODATA ? 0 : 2, 1) >= 0){ int rv; if(km_popped){ term.t_mrow = 2; curwp->w_ntrows -= 2; curwp->w_flag |= WFHARD; km_popped = 0; } clearcursor(); mlerase(); rv = (*Pmaster->showmsg)(c); ttresize(); picosigs(); /* restore altered handlers */ if(rv) /* Did showmsg corrupt the display? */ PaintBody(0); /* Yes, repaint */ mpresf = 1; input = 0; } clearcursor(); movecursor(0, 0); } if(km_popped) switch(c){ case NODATA: case (CTRL|'L'): km_popped++; break; default: mlerase(); break; } if(c == NODATA) /* no op, getkey timed out */ continue; else if(!input++) (*Pmaster->keybinput)(); if (mpresf != FALSE) { /* message stay around only */ if (mpresf++ > NMMESSDELAY) /* so long! */ mlerase(); } f = FALSE; /* vestigial */ n = 1; /* Do it. */ execute(normalize_cmd(c, pfkm, 2), f, n); if(++checkpointcnt >= CHKPTDELAY){ checkpointcnt = 0; writeout(chkptfile, TRUE); } } }