/*-1* Copyright (c) 2013-2014 Devin Teske <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#include <sys/cdefs.h>27#include <curses.h>28#include <dialog.h>29#include <stdarg.h>30#include <stdlib.h>31#include <string.h>3233#include "dialog_util.h"34#include "status.h"3536/* static globals */37static char *status_buf = NULL;38static int status_bufsize = -1;39static int status_row;40static int status_width;4142/*43* Print a `one-liner' status message at the bottom of the screen. Messages are44* trimmed to fit within the console length (ANSI coloring not accounted for).45*/46void47status_printf(const char *fmt, ...)48{49int n, attrs;50chtype color = dlg_color_pair(dlg_color_table[BUTTON_ACTIVE_ATTR].fg,51dlg_color_table[SCREEN_ATTR].bg) | A_BOLD;52va_list args;5354status_row = tty_maxrows() - 1;55status_width = tty_maxcols();5657/* NULL is a special convention meaning "erase the old stuff" */58if (fmt == NULL) {59move(status_row, 0);60clrtoeol();61return;62}6364/* Resize buffer if terminal width is greater */65if ((status_width + 1) > status_bufsize) {66status_buf = realloc(status_buf, status_width + 1);67if (status_buf == NULL) {68status_bufsize = -1;69return;70}71status_bufsize = status_width + 1;72}7374/* Print the message within a space-filled buffer */75memset(status_buf, ' ', status_width);76va_start(args, fmt);77n = vsnprintf(status_buf, status_width + 1, fmt, args);78va_end(args);7980/* If vsnprintf(3) produced less bytes than the maximum, change the81* implicitly-added NUL-terminator into a space and terminate at max */82if (n < status_width) {83status_buf[n] = ' ';84status_buf[status_width] = '\0';85}8687/* Print text in screen bg, button active fg, and bold */88attrs = getattrs(stdscr);89attrset(color);90mvaddstr(status_row, 0, status_buf);91attrset(attrs);9293/* Seat the cursor over the last character at absolute lower-right */94move(status_row, status_width - 1);95refresh();96}9798/*99* Free allocated items initialized by status_printf()100*/101void102status_free(void)103{104if (status_buf != NULL) {105free(status_buf);106status_buf = NULL;107}108}109110111