1 /*- 2 * Copyright (c) 2013-2014 Devin Teske <dteske@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <curses.h> 31 #include <dialog.h> 32 #include <stdarg.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 #include "dialog_util.h" 37 #include "status.h" 38 39 /* static globals */ 40 static char *status_buf = NULL; 41 static int status_bufsize = -1; 42 static int status_row; 43 static int status_width; 44 45 /* 46 * Print a `one-liner' status message at the bottom of the screen. Messages are 47 * trimmed to fit within the console length (ANSI coloring not accounted for). 48 */ 49 void 50 status_printf(const char *fmt, ...) 51 { 52 int n, attrs; 53 chtype color = dlg_color_pair(dlg_color_table[BUTTON_ACTIVE_ATTR].fg, 54 dlg_color_table[SCREEN_ATTR].bg) | A_BOLD; 55 va_list args; 56 57 status_row = tty_maxrows() - 1; 58 status_width = tty_maxcols(); 59 60 /* NULL is a special convention meaning "erase the old stuff" */ 61 if (fmt == NULL) { 62 move(status_row, 0); 63 clrtoeol(); 64 return; 65 } 66 67 /* Resize buffer if terminal width is greater */ 68 if ((status_width + 1) > status_bufsize) { 69 status_buf = realloc(status_buf, status_width + 1); 70 if (status_buf == NULL) { 71 status_bufsize = -1; 72 return; 73 } 74 status_bufsize = status_width + 1; 75 } 76 77 /* Print the message within a space-filled buffer */ 78 memset(status_buf, ' ', status_width); 79 va_start(args, fmt); 80 n = vsnprintf(status_buf, status_width + 1, fmt, args); 81 va_end(args); 82 83 /* If vsnprintf(3) produced less bytes than the maximum, change the 84 * implicitly-added NUL-terminator into a space and terminate at max */ 85 if (n < status_width) { 86 status_buf[n] = ' '; 87 status_buf[status_width] = '\0'; 88 } 89 90 /* Print text in screen bg, button active fg, and bold */ 91 attrs = getattrs(stdscr); 92 attrset(color); 93 mvaddstr(status_row, 0, status_buf); 94 attrset(attrs); 95 96 /* Seat the cursor over the last character at absolute lower-right */ 97 move(status_row, status_width - 1); 98 refresh(); 99 } 100 101 /* 102 * Free allocated items initialized by status_printf() 103 */ 104 void 105 status_free(void) 106 { 107 if (status_buf != NULL) { 108 free(status_buf); 109 status_buf = NULL; 110 } 111 } 112