Esempio n. 1
0
/*
 * 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);
}
Esempio n. 2
0
File: pico.c Progetto: ctubio/alpine
/*
 * 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);
	}
    }
}