static char rcsid[] = "@(#)$Id: termbuffer.c,v 1.5 2006/04/09 07:37:37 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.5 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
 *****************************************************************************/

#include "def_screen.h"
#include <errno.h>

DEBUG_VAR(Debug,__FILE__,"screen");

int terminal_fd = 1;   /* Standard output, later terminal ... */

static char outchar_write_buffer[2048];
VOLATILE static char * buffer_ptr = &(outchar_write_buffer[0]);

/* Note that there is several race conditions -- losing of characters possible 
   (this may be called from signal handler)
*/
void FlushBuffer P_((void))
{
    int len; 

    while (0 < (len = buffer_ptr-outchar_write_buffer)) {
	int L = write(terminal_fd,outchar_write_buffer,len);
	int err = errno;

	if (L < 0 && 
	    ((err != EINTR)
#ifdef	EAGAIN
	     && (err != EAGAIN)
#endif
#ifdef	EWOULDBLOCK
	     && (err != EWOULDBLOCK)
#endif
	     )) {
	    SIGDPRINT(Debug,4,(&Debug, 			       
			       "FlushBuffer: Write failed errno=%d\n",err));
	    break;
	}	   

	if (L > 0) {
	    len = buffer_ptr-outchar_write_buffer;

	    len -= L;

	    DPRINT(Debug,9,(&Debug,
			    "FlushBuffer: %d bytes writted to %d, %d left\n",
			    L,terminal_fd,len));

	    if (len > 0)
		memmove(outchar_write_buffer,outchar_write_buffer+L,len);
	    if (len >= 0)
		buffer_ptr = outchar_write_buffer + len;
	    else
		buffer_ptr = outchar_write_buffer;

	} else {
	    DPRINT(Debug,2,(&Debug,
			    "FlushBuffer: Looping...\n"));
	}
    }   
}

/* Note that there is several race conditions -- losing of characters possible 
   (this may be called from signal handler)
*/
int outchar(c)
     int c;
{

    if (buffer_ptr >= outchar_write_buffer + sizeof (outchar_write_buffer))
	FlushBuffer();
   
    if (buffer_ptr < outchar_write_buffer + sizeof (outchar_write_buffer)) {
	VOLATILE char *p = buffer_ptr++;
	
	*p = c;
	
	if (c >= ' ' && c < 127) {  /* ASCII Assumed */
	    SIGDPRINT(Debug,40,(&Debug, 
				"outchar [%d] = %02X '%c'\n",
				p-outchar_write_buffer,(unsigned char) *p,c));

	} else {
	    SIGDPRINT(Debug,40,(&Debug, 
				"outchar [%d] = %02X\n",
				p-outchar_write_buffer,(unsigned char) *p));
	}

	return (unsigned char)c;
    }
    SIGDPRINT(Debug,2,(&Debug,
		       "outchar: Buffer full!\n"));
    return EOF;
}

/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1