/******************************************************************************
* This file is part of a software distribution, which is furnished under the *
* terms of a license. Use of this software by any means is subject to this *
* license and signifies the acceptance of the licensing terms stated *
* therein. Please see the file LICENSE in the top-level directory of this *
* software distribution for detailed copyright disclaimers and licensing *
* terms. *
******************************************************************************
* Copryight (c) by Andreas S. Wetzel - All rights reserved. *
******************************************************************************/
/* $Id: statusbar.c,v 1.2 2001/03/19 14:54:02 mickey Exp $ */
#include <vchat.h>
#include <proto_common.h>
#include <sys/ioctl.h>
/*** Globals ***/
u_long var_space = 0;
STAT_ITEM st_item[STAT_MAX];
u_char prio_to_item[] =
{
STAT_LOGO,
STAT_VARSP,
STAT_FLAGS,
STAT_CLOCK,
STAT_CHAN,
STAT_NICK,
STAT_SERVER,
STAT_ONLINE,
STAT_SIZE,
STAT_TERM
};
u_char item_to_prio[] = {0, 2, 3, 6, 7, 5, 4, 1, 9, 8};
/*** Externals ***/
extern int in_chat_window;
extern VP vp;
extern ED *ed;
extern VTCAP vtcap;
extern VCONN sconn;
/*** Code ***/
void init_status(void)
{
u_char tbuf[6];
time_t now;
time(&now);
BZERO(&tbuf, 6);
strftime(tbuf, 6, "%H:%M", localtime(&now));
/*
* Initialize certain commandline elements
*/
alter_status(STAT_LOGO, " VChat ");
update_flags();
alter_status(STAT_CLOCK, "%s ", tbuf);
alter_status(STAT_ONLINE, "00:00 ");
alter_status(STAT_NICK, "%s ", vp.nick);
alter_status(STAT_CHAN, "%d ", 0);
alter_status(STAT_TERM, "%s ", vp.emulation);
alter_status(STAT_SIZE, "%dx%d ", vtcap.cols, vtcap.rows);
alter_status(STAT_SERVER, "%s ", sconn.host);
}
void alter_status(u_char item, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsprintf(st_item[item].buf, fmt, ap);
st_item[item].flags |= NEEDS_UPDATE;
va_end(ap);
}
void update_flags(void)
{
u_char statbuf[] = "_ _ _";
if(vp.logswitch == 1)
statbuf[4] = 'L';
if(vp.cmdmode == 1)
statbuf[0] = 'S';
alter_status(STAT_FLAGS, "%s ", statbuf);
update_status(0);
}
void update_status(u_char redraw)
{
static u_char old_prio = -1;
static u_short old_size_x = -1;
static u_short old_size_y = -1;
u_char maxpri;
/*
* Lock out signals until completed
*/
vlock(LOCK, (V_IO | V_TIMER | V_WINCH));
/*
* Calculate max priority
*/
maxpri = status_maxpriority();
/*
* Check if window size or priority
* has changed since last update.
*/
if(redraw || maxpri != old_prio || vtcap.cols != old_size_x || vtcap.rows != old_size_y)
{
full_update(maxpri);
}
else
{
optimized_update(maxpri);
}
old_size_x = vtcap.cols;
old_size_y = vtcap.rows;
old_prio = maxpri;
/*
* Release SIGWINCH
*/
vlock(UNLOCK, (V_IO | V_TIMER | V_WINCH));
}
/*
* Berechnen der maximalen Prioritaet die
* bei der aktuellen Bildschirmbreite
* zur Ausgabe kommen kann, sowie der
* Breite des variablen space.
*/
u_char status_maxpriority(void)
{
int size = 0;
u_char prio = 0;
for(prio = 0; prio < STAT_MAX; prio++)
{
if(prio_to_item[prio] == STAT_VARSP)
continue;
if((size + strlen(st_item[prio_to_item[prio]].buf)) <= vtcap.cols)
size += strlen(st_item[prio_to_item[prio]].buf);
else
break;
}
var_space = (vtcap.cols - size);
return(prio-1);
}
void full_update(u_char maxpri)
{
u_char i;
if(HAS_SRC && !in_chat_window)
tputs(vtcap.csave, 1, (void *)outc);
mv(1, (vtcap.rows - 1));
if(HAS_COLOR)
{
tputs(vtcap.off, 1, (void *)outc);
tputs(tparm(vtcap.set_fg_color, 7), 1, (void *)outc);
tputs(tparm(vtcap.set_bg_color, 4), 1, (void *)outc);
}
else
{
tputs(vtcap.reverse, 1, (void *)outc);
}
if(vtcap.bold)
tputs(vtcap.bold, 1, (void *)outc);
for(i = 0; i < STAT_MAX; i++)
{
if(item_to_prio[i] > maxpri)
continue;
if(i == STAT_VARSP)
{
printf("%*s", (int)var_space, " ");
st_item[i].size = var_space;
}
else if(i == STAT_LOGO)
{
if(HAS_COLOR)
{
tputs(tparm(vtcap.set_fg_color, 5), 1, (void *)outc);
printf(" V");
tputs(tparm(vtcap.set_fg_color, 3), 1, (void *)outc);
printf("Chat ");
tputs(tparm(vtcap.set_fg_color, 7), 1, (void *)outc);
}
else
{
printf("%s", st_item[i].buf);
}
st_item[i].size = strlen(st_item[i].buf);
}
else
{
printf("%s", st_item[i].buf);
st_item[i].size = strlen(st_item[i].buf);
}
st_item[i].flags &= ~NEEDS_UPDATE;
}
if(vtcap.off)
tputs(vtcap.off, 1, (void *)outc);
if(HAS_SRC && !in_chat_window)
{
tputs(vtcap.crestore, 1, (void *)outc);
}
else
{
mv(ED_SCRPOS, vtcap.rows);
in_chat_window = 0;
}
}
void optimized_update(u_char maxpri)
{
u_short offset = 1;
u_char has_changed = 0;
u_char action = 0;
u_char i;
for(i = 0; i < STAT_MAX; i++)
{
/*
* Skip items with priority > maxpri
*/
if(item_to_prio[i] > maxpri)
continue;
/*
* Optimize update
*/
if(!has_changed)
{
if(st_item[i].flags & NEEDS_UPDATE)
{
if(HAS_SRC && !in_chat_window && !action)
tputs(vtcap.csave, 1, (void *)outc);
mv(offset, (vtcap.rows - 1));
if(!action)
{
action = 0xff;
if(HAS_COLOR)
{
tputs(tparm(vtcap.set_bg_color, 4), 1, (void *)outc);
tputs(tparm(vtcap.set_fg_color, 7), 1, (void *)outc);
}
else
{
tputs(vtcap.reverse, 1, (void *)outc);
}
if(vtcap.bold)
tputs(vtcap.bold, 1, (void *)outc);
}
if(strlen(st_item[i].buf) != st_item[i].size)
has_changed = 0xff;
if(i == STAT_VARSP)
{
printf("%*s", (int)var_space, " ");
st_item[i].size = var_space;
}
else if(i == STAT_LOGO)
{
if(HAS_COLOR)
{
tputs(tparm(vtcap.set_fg_color, 5), 1, (void *)outc);
printf(" V");
tputs(tparm(vtcap.set_fg_color, 3), 1, (void *)outc);
printf("Chat ");
tputs(tparm(vtcap.set_fg_color, 7), 1, (void *)outc);
}
else
{
printf("%s", st_item[i].buf);
}
st_item[i].size = strlen(st_item[i].buf);
}
else
{
printf("%s", st_item[i].buf);
st_item[i].size = strlen(st_item[i].buf);
}
st_item[i].flags &= ~NEEDS_UPDATE;
offset += st_item[i].size;
}
else
{
offset += st_item[i].size;
continue;
}
}
else
{
if(i == STAT_VARSP)
{
printf("%*s", (int)var_space, " ");
st_item[i].size = var_space;
}
else if(i == STAT_LOGO)
{
if(HAS_COLOR)
{
tputs(tparm(vtcap.set_fg_color, 5), 1, (void *)outc);
printf(" V");
tputs(tparm(vtcap.set_fg_color, 3), 1, (void *)outc);
printf("Chat ");
tputs(tparm(vtcap.set_fg_color, 7), 1, (void *)outc);
}
else
{
printf("%s", st_item[i].buf);
}
st_item[i].size = strlen(st_item[i].buf);
}
else
{
printf("%s", st_item[i].buf);
st_item[i].size = strlen(st_item[i].buf);
}
st_item[i].flags &= ~NEEDS_UPDATE;
}
} /* Loop */
if(action)
{
if(vtcap.off)
tputs(vtcap.off, 1, (void *)outc);
if(HAS_SRC && !in_chat_window)
{
tputs(vtcap.crestore, 1, (void *)outc);
}
else
{
mv(ED_SCRPOS, vtcap.rows);
in_chat_window = 0;
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1