static char rcsid[] = "@(#)$Id: out_utils.c,v 1.33 2006/04/16 21:01:35 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.33 $ $State: Exp $
*
* Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI>
* (was hurtta+elm@ozone.FMI.FI)
******************************************************************************
* The Elm Mail System
*
* Copyright (c) 1988-1992 USENET Community Trust
* Copyright (c) 1986,1987 Dave Taylor
*****************************************************************************/
/** This file contains routines used for output in the ELM program.
**/
#include "def_elm.h"
DEBUG_VAR(Debug,__FILE__,"ui");
static char err_buffer[SLEN]; /* store last error message */
static time_t LAST_ERROR = 0;
static int is_cancel_error = 0;
static void error_middle P_((CONST char *s));
void show_last_error()
{
/** rewrite last error message! **/
if(RawState()) {
error_middle(err_buffer);
}
}
void error_wait()
{
time_t M = time(NULL);
if (LAST_ERROR + sleepmsg > M && RawState()) {
int W = LAST_ERROR + sleepmsg - M;
DPRINT(Debug,7,(&Debug,
"sleeping for %d seconds for error message\n",
W));
FlushBuffer();
error_sleep(W);
}
}
void clear_error()
{
if(RawState()) {
int LINES, COLUMNS;
menu_get_sizes(default_context,&LINES, &COLUMNS);
if ('\0' != err_buffer[0])
error_wait();
MoveCursor(LINES-1,0);
CleartoEOLN();
err_buffer[0] = '\0';
is_cancel_error = 0;
}
}
void Raw_OFF(exiting)
int exiting;
{
if(RawState()) {
int LINES, COLUMNS;
menu_get_sizes(default_context,&LINES, &COLUMNS);
if ('\0' != err_buffer[0])
error_wait();
MoveCursor(LINES-1,0);
CleartoEOLN();
}
Raw(OFF);
NewLine();
if (exiting)
switch_title(2);
if ('\0' != err_buffer[0])
error_middle(err_buffer);
FlushBuffer();
}
void set_error(s)
char *s;
{
strfcpy(err_buffer, s, sizeof err_buffer);
}
static void error_help P_((CONST char *s));
static void error_help (s)
CONST char *s;
{
int LINES, COLUMNS;
menu_get_sizes(default_context,&LINES, &COLUMNS);
MoveCursor(LINES-1,0);
CleartoEOLN();
PutLine0(LINES-1,(COLUMNS-strlen(s))/2,s);
FlushBuffer();
}
static void error_middle (s)
CONST char *s;
{
if(!RawState()) {
fprintf(stderr,"%s\n", s);
/* sleep if stderr points to terminal
*/
if (isatty(2)) {
#if POLL_METHOD
wait_for_timeout(1);
#else
sleep(1);
#endif
}
} else {
int LINES, COLUMNS;
menu_get_sizes(default_context,&LINES, &COLUMNS);
if (strlen(s) < COLUMNS && NULL == strchr(s,'\n'))
error_help(s);
else {
char * s1 = safe_strdup(s);
char *s2, *s3;
for (s2=s1; *s2 != '\0'; s2 = s3) {
char c;
for (s3 = s2; *s3 != '\0' && s3 - s2 < COLUMNS && *s3 != '\n'; s3++);
c = *s3;
*s3 = '\0';
error_help(s2);
*s3 = c;
if ('\n' == c)
s3++;
if (*s3 != '\0') { /* Wait between lines ...*/
error_sleep(1);
}
}
free(s1);
}
}
strfcpy(err_buffer, s, sizeof err_buffer); /* save it too! */
}
int error(s)
CONST char *s;
{
/** outputs error 's' to screen at line 22, centered! **/
if (0 == strcmp(err_buffer,s)) {
DPRINT(Debug,7,(&Debug,
"-- duplicate error message\n"));
} else {
error_wait();
LAST_ERROR = time(NULL);
}
DPRINT(Debug,1,(&Debug,
"ERROR message: %s\n",
s));
error_middle(s);
return 0;
}
static int transient P_((CONST char *s));
static int transient(s)
CONST char *s;
{
/** outputs error 's' to screen at line 22, centered! **/
DPRINT(Debug,1,(&Debug,
"TRANSIENT message: %s\n",
s));
LAST_ERROR = 0; /* NO SLEEP */
error_middle(s);
strfcpy(err_buffer, s, sizeof err_buffer); /* save it too! */
return 0;
}
static char * prompt_it P_((CONST char *str, int pass));
static char * prompt_it (str,pass)
CONST char *str;
int pass;
{
int len = strlen(str);
int status;
char buffer[200];
int oldstate = RawState();
int LINES, COLUMNS;
struct menu_context *cpage = Raw(ON);
buffer[0] = '\0';
redraw:
menu_get_sizes(cpage,&LINES, &COLUMNS);
PutLine0(LINES-3, 0,str);
CleartoEOS();
show_last_error();
status = optionally_enter(buffer,LINES-1-2, len+1,
(pass ? OE_PASSWD : 0) |OE_REDRAW_MARK|
OE_SIG_CHAR /* Ctrl-C */,
sizeof buffer,
cpage);
if (REDRAW_MARK == status) {
menu_ClearScreen(cpage); /* Clear possible redraw mark */
/* Call refresh routines of children */
menu_redraw_children(cpage);
goto redraw;
}
MoveCursor(LINES-3,0); /* Ack RETURN */
CleartoEOS();
Raw(oldstate);
show_last_error();
if (status != 0)
return NULL;
return safe_strdup(buffer);
}
static void cancel_transient_X P_((struct string *x));
static void cancel_transient_X(x)
struct string *x;
{
int LINES, COLUMNS;
int pos = 0;
int vlen;
struct string *Y;
int s = 0;
clear_error();
menu_get_sizes(default_context,&LINES, &COLUMNS);
DPRINT(Debug,1,(&Debug,
"CANCEL TRANSIENT message: %S\n",
x));
is_cancel_error = 1;
while (NULL != (Y = curses_printable_clip(x,&pos,99,&vlen,COLUMNS-1))) {
if (vlen > 0) {
if (s)
error_sleep(1);
s = 1;
MoveCursor(LINES-1,0);
CleartoEOLN();
PutLineX(LINES-1,(COLUMNS-vlen)/2,FRM("%S"),Y);
FlushBuffer();
}
free_string(&Y);
if (!vlen)
break;
}
}
static void cancel_clear_X P_((void));
static void cancel_clear_X()
{
int LINES, COLUMNS;
menu_get_sizes(default_context,&LINES, &COLUMNS);
MoveCursor(LINES-1,0);
CleartoEOLN();
is_cancel_error = 0;
}
void out_util_setup() {
set_error_handler(error);
set_transient_handler(transient);
set_prompt_handler(prompt_it);
setup_cancel_cb(cancel_set_ttysig_X,
cancel_reset_ttysig_X,
cancel_transient_X,
cancel_clear_X);
}
/* Used by newmbox.c */
int need_refresh_low_line() {
if ('\0' != err_buffer[0]) {
clear_error();
return 1;
}
if (is_cancel_error) {
cancel_clear_X();
return 1;
}
return 0;
}
void lower_prompt(s)
char *s;
{
/** prompt user for input on LINES-1 line, left justified **/
if(RawState()) {
int LINES, COLUMNS;
menu_get_sizes(default_context,&LINES, &COLUMNS);
PutLine0(LINES-1-1,0,s);
CleartoEOLN();
} else {
fprintf(stderr,"%s\n",s);
}
}
void prompt(s)
char *s;
{
/** prompt user for input on LINES-3 line, left justified **/
if(RawState()) {
int LINES, COLUMNS;
menu_get_sizes(default_context,&LINES, &COLUMNS);
PutLine0(LINES-4,0,s);
CleartoEOLN();
} else {
fprintf(stderr,"%s\n",s);
}
}
void prompt_s(page,S)
struct menu_context *page;
CONST struct string *S;
{
/** prompt user for input on LINES-3 line, left justified **/
if(RawState()) {
int LINES, COLUMNS;
menu_get_sizes(page,&LINES, &COLUMNS);
menu_PutLineX(page,LINES-4,0,FRM("%S"),S);
menu_CleartoEOLN(page);
} else {
lib_transient(FRM("%S\n"),S);
}
}
void sleep_message() {
if (sleepmsg > 0) {
error_sleep(sleepmsg);
}
}
void print_center(line,buffer)
int line;
struct string * buffer;
{
int l1 = string_len(buffer);
int LINES, COLUMNS;
menu_get_sizes(default_context,&LINES, &COLUMNS);
if (l1 < COLUMNS)
PutLineX(line,(COLUMNS - l1)/2,FRM("%S"),buffer);
}
void menu_print_center(ptr,line,buffer)
struct menu_context *ptr;
int line;
struct string * buffer;
{
int l1 = string_len(buffer);
int LINES, COLUMNS;
menu_get_sizes(ptr,&LINES, &COLUMNS);
if (l1 < COLUMNS)
menu_PutLineX(ptr,line,(COLUMNS - l1)/2,FRM("%S"),buffer);
}
void menu_print_format_center(
#if ANSI_C
struct menu_context *ptr,
int lineY,const char *format, const char *line, ...
#else
ptr,lineY,format,line,va_alist
#endif
)
#if !ANSI_C
struct menu_context *ptr;
int lineY;
CONST char *format;
CONST char *line;
va_dcl
#endif
{
va_list vl;
struct string *text;
Va_start(vl, line); /* defined in defs.h */
text = elm_smessage(0,format,line,vl);
va_end(vl);
menu_print_center(ptr,lineY,text);
free_string(&text);
}
void print_format_center(
#if ANSI_C
int lineY,const char *format, const char *line, ...
#else
lineY,format,line,va_alist
#endif
)
#if !ANSI_C
int lineY;
CONST char *format;
CONST char *line;
va_dcl
#endif
{
va_list vl;
struct string *text;
Va_start(vl, line); /* defined in defs.h */
text = elm_smessage(0,format,line,vl);
va_end(vl);
print_center(lineY,text);
free_string(&text);
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1