/****************************************************************************** * 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 #include #include /*** 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; } } }