diff --git a/src/intf.c b/src/intf.c index 5b2b9a7..d9b246a 100644 --- a/src/intf.c +++ b/src/intf.c @@ -252,30 +252,41 @@ int txrefresh (void) } -/************************************************************************ -* Output routines * -************************************************************************/ +/***********************************************************************/ +// attrpr: Print a string with a particular character rendition -/*----------------------------------------------------------------------- - Function: center - Centre a string on the current line - Arguments: win - Window to use - y - Line on which to centre the string - attr - Window attributes to use for string - format - printf()-like format string - ... - printf()-like arguments - Returns: int - Return code from wprintw() - - This function prints a string (formated with wprintw(format, ...)) in - the centre of line y in the window win, using the window attributes in - attr. Please note that wrefresh() is NOT called. -*/ - -int center (WINDOW *win, int y, int attr, const char *format, ...) +int attrpr (WINDOW *win, chtype attr, const char *restrict format, ...) { va_list args; + int ret; - int oldattr; - int len, ret, x; + chtype oldattr = getattrs(win); + chtype oldbkgd = getbkgd(win); + + + /* Note that wattrset() will override parts of wbkgdset() and vice + versa: don't swap the order of these two lines! */ + wbkgdset(win, (oldbkgd & A_COLOR) | A_NORMAL); + wattrset(win, attr); + + va_start(args, format); + ret = vw_printw(win, format, args); + va_end(args); + + wbkgdset(win, oldbkgd); + wattrset(win, oldattr); + + return ret; +} + + +/***********************************************************************/ +// center: Centre a string in a given window + +int center (WINDOW *win, int y, chtype attr, const char *restrict format, ...) +{ + va_list args; + int ret, len, x; char *buf; @@ -284,54 +295,42 @@ int center (WINDOW *win, int y, int attr, const char *format, ...) err_exit_nomem(); } - oldattr = getbkgd(win) & ~A_CHARTEXT; - wbkgdset(win, A_NORMAL | (oldattr & A_COLOR)); + chtype oldattr = getattrs(win); + chtype oldbkgd = getbkgd(win); + + // Order is important: see attrpr() + wbkgdset(win, (oldbkgd & A_COLOR) | A_NORMAL); wattrset(win, attr); va_start(args, format); len = vsnprintf(buf, BUFSIZE, format, args); va_end(args); + if (len < 0) { - free(buf); - return ERR; + ret = ERR; + } else if (len == 0) { + ret = OK; + } else { + x = (getmaxx(win) - len) / 2; + ret = mvwprintw(win, y, MAX(x, 2), "%1.*s", getmaxx(win) - 4, buf); } - x = (getmaxx(win) - len) / 2; - ret = mvwprintw(win, y, MAX(x, 2), "%1.*s", getmaxx(win) - 4, buf); - + wbkgdset(win, oldbkgd); wattrset(win, oldattr); - wbkgdset(win, oldattr); free(buf); return ret; } -/*----------------------------------------------------------------------- - Function: center2 - Centre two strings on the current line - Arguments: win - Window to use - y - Line on which to centre the string - attr_initial - Window attribute to use for initial string - attr_string - Window attribute to use for main string - initial - Fixed initial string - format - printf()-like format string - ... - printf()-like arguments - Returns: int - Return code from wprintw() +/***********************************************************************/ +// center2: Centre two strings in a given window - This function prints two strings in the centre of line y in the window - win. The initial string is printed using the window attributes in - attr_initial; the main string uses attr_string. No spaces appear - between the two strings. Please note that wrefresh() is NOT called. -*/ - -int center2 (WINDOW *win, int y, int attr_initial, int attr_string, - const char *initial, const char *format, ...) +int center2 (WINDOW *win, int y, chtype attr1, chtype attr2, + const char *initial, const char *restrict format, ...) { va_list args; - - int oldattr; - int len1, len2; - int ret, x; + int ret, len1, len2, x; char *buf; @@ -340,60 +339,45 @@ int center2 (WINDOW *win, int y, int attr_initial, int attr_string, err_exit_nomem(); } - oldattr = getbkgd(win) & ~A_CHARTEXT; - wbkgdset(win, A_NORMAL | (oldattr & A_COLOR)); + chtype oldattr = getattrs(win); + chtype oldbkgd = getbkgd(win); + + wbkgdset(win, (oldbkgd & A_COLOR) | A_NORMAL); len1 = strlen(initial); va_start(args, format); len2 = vsnprintf(buf, BUFSIZE, format, args); va_end(args); + if (len2 < 0) { - free(buf); - return ERR; + ret = ERR; + } else if (len1 + len2 == 0) { + ret = OK; + } else { + x = (getmaxx(win) - (len1 + len2)) / 2; + wattrset(win, attr1); + mvwprintw(win, y, MAX(x, 2), "%s", initial); + wattrset(win, attr2); + ret = wprintw(win, "%1.*s", getmaxx(win) - len1 - 4, buf); } - x = (getmaxx(win) - (len1 + len2)) / 2; - wattrset(win, attr_initial); - mvwprintw(win, y, MAX(x, 2), "%s", initial); - wattrset(win, attr_string); - ret = wprintw(win, "%1.*s", getmaxx(win) - len1 - 4, buf); - + wbkgdset(win, oldbkgd); wattrset(win, oldattr); - wbkgdset(win, oldattr); free(buf); return ret; } -/*----------------------------------------------------------------------- - Function: center3 - Centre three strings on the current line - Arguments: win - Window to use - y - Line on which to centre the string - attr_initial - Window attribute to use for initial string - attr_final - Window attribute to use for final string - attr_string - Window attribute to use for main string - initial - Fixed initial string - final - Fixed final string - format - printf()-like format string - ... - printf()-like arguments - Returns: int - Return code from wprintw() +/***********************************************************************/ +// center3: Centre three strings in a given window - This function prints three strings in the centre of line y in the - window win. The initial string is printed using the window attributes - in attr_initial, the main string uses attr_string and the final string - uses attr_final. No spaces appear between the three strings. Please - note that wrefresh() is NOT called. Also note ordering of parameters! -*/ - -int center3 (WINDOW *win, int y, int attr_initial, int attr_final, - int attr_string, const char *initial, const char *final, - const char *format, ...) +int center3 (WINDOW *win, int y, chtype attr1, chtype attr3, chtype attr2, + const char *initial, const char *final, + const char *restrict format, ...) { va_list args; - - int oldattr; int len1, len2, len3; int ret, x; char *buf; @@ -404,8 +388,10 @@ int center3 (WINDOW *win, int y, int attr_initial, int attr_final, err_exit_nomem(); } - oldattr = getbkgd(win) & ~A_CHARTEXT; - wbkgdset(win, A_NORMAL | (oldattr & A_COLOR)); + chtype oldattr = getattrs(win); + chtype oldbkgd = getbkgd(win); + + wbkgdset(win, (oldbkgd & A_COLOR) | A_NORMAL); len1 = strlen(initial); len3 = strlen(final); @@ -413,61 +399,29 @@ int center3 (WINDOW *win, int y, int attr_initial, int attr_final, va_start(args, format); len2 = vsnprintf(buf, BUFSIZE, format, args); va_end(args); + if (len2 < 0) { - free(buf); - return ERR; + ret = ERR; + } else if (len1 + len2 + len3 == 0) { + ret = OK; + } else { + x = (getmaxx(win) - (len1 + len2 + len3)) / 2; + wattrset(win, attr1); + mvwprintw(win, y, MAX(x, 2), "%s", initial); + wattrset(win, attr2); + ret = wprintw(win, "%1.*s", getmaxx(win) - len1 - len3 - 4, buf); + wattrset(win, attr3); + wprintw(win, "%s", final); } - x = (getmaxx(win) - (len1 + len2 + len3)) / 2; - wattrset(win, attr_initial); - mvwprintw(win, y, MAX(x, 2), "%s", initial); - wattrset(win, attr_string); - ret = wprintw(win, "%1.*s", getmaxx(win) - len1 - len3 - 4, buf); - wattrset(win, attr_final); - wprintw(win, "%s", final); - + wbkgdset(win, oldbkgd); wattrset(win, oldattr); - wbkgdset(win, oldattr); free(buf); return ret; } -/*----------------------------------------------------------------------- - Function: attrpr - Print a string with special attributes - Arguments: win - Window to use - attr - Attribute to use for the string - format - printf()-like format string - ... - printf()-like arguments - Returns: int - Return code from wprintw() - - This function sets the window attributes to attr, then prints the given - string (using wprintw()), then restores the previous window attributes. -*/ - -int attrpr (WINDOW *win, int attr, const char *format, ...) -{ - va_list args; - int oldattr; - int ret; - - - oldattr = getbkgd(win) & ~A_CHARTEXT; - wbkgdset(win, A_NORMAL | (oldattr & A_COLOR)); - wattrset(win, attr); - - va_start(args, format); - ret = vw_printw(win, format, args); - va_end(args); - - wattrset(win, oldattr); - wbkgdset(win, oldattr); - - return ret; -} - - /************************************************************************ * Input routines * ************************************************************************/ diff --git a/src/intf.h b/src/intf.h index 2659963..9ffc4b0 100644 --- a/src/intf.h +++ b/src/intf.h @@ -286,22 +286,103 @@ extern int delalltxwin (void); extern int txrefresh (void); -// Output routines +/* + Function: attrpr - Print a string with a particular character rendition + Parameters: win - Window to use (should be curwin) + attr - Character rendition to use for the string + format - printf()-like format string + ... - printf()-like arguments + Returns: int - Return code from wprintw(): OK or ERR -extern int center (WINDOW *win, int y, int attr, const char *format, ...) + This function sets the character rendition (attributes) to attr, prints + the string using wprintw(), then restores the previous character + rendition. The return code is as returned from wprintw(). Note that + wrefresh() is NOT called. +*/ +extern int attrpr (WINDOW *win, chtype attr, const char *restrict format, ...) + __attribute__((format (printf, 3, 4))); + + +/* + Function: center - Centre a string in a given window + Parameters: win - Window to use (should be curwin) + y - Line on which to centre the string + attr - Character rendition to use for the string + format - printf()-like format string + ... - printf()-like arguments + Returns: int - Return code from wprintw(): OK or ERR + + This function prints a string formatted with wprintw() in the centre of + line y in the window win, using the character rendition (attributes) in + attr. If the string is too long to fit the window, it is truncated. + Please note that wrefresh() is NOT called. + + At the current time, the implementation of this function does NOT + handle multibyte strings correctly: strlen() is used to determine the + printing width of the string. +*/ +extern int center (WINDOW *win, int y, chtype attr, + const char *restrict format, ...) __attribute__((format (printf, 4, 5))); -extern int center2 (WINDOW *win, int y, int attr_initial, int attr_string, - const char *initial, const char *format, ...) + +/* + Function: center2 - Centre two strings in a given window + Parameters: win - Window to use (should be curwin) + y - Line on which to centre the strings + attr1 - Character rendition to use for initial string + attr2 - Character rendition to use for main string + initial - Initial string (no printf() formatting) + format - printf()-like format string for main string + ... - printf()-like arguments + Returns: int - Return code from wprintw(): OK or ERR + + This function prints two strings side-by-side on line y in the centre + of window win. The first (initial) string is printed with character + rendition (attributes) attr1 using waddstr(). The second (main) string + uses wprintw(format, ...) with rendition attr2. If the main string is + too long to fit in the window alongside the initial string, the main + string is truncated to fit. Please note that wrefresh() is NOT called. + + As with center(), the current implementation does NOT handle multibyte + strings correctly. +*/ +extern int center2 (WINDOW *win, int y, chtype attr1, chtype attr2, + const char *initial, const char *restrict format, ...) __attribute__((format (printf, 6, 7))); -extern int center3 (WINDOW *win, int y, int attr_initial, int attr_final, - int attr_string, const char *initial, const char *final, - const char *format, ...) + +/* + Function: center3 - Centre three strings in a given window + Parameters: win - Window to use (should be curwin) + y - Line on which to centre the strings + attr1 - Character rendition to use for initial string + attr3 - Character rendition to use for final string + attr2 - Character rendition to use for main string + initial - Initial string (no printf() formatting) + final - Final string (no printf() formatting) + format - printf()-like format string for main string + ... - printf()-like arguments + Returns: int - Return code from wprintw(): OK or ERR + + This function prints three strings side-by-side on line y in the centre + of window win. The first (initial) string is printed with character + rendition (attributes) attr1 using waddstr(). The second (main) string + uses wprintw(format, ...) with rendition attr2. The third (final) + string is then printed with rendition attr3 using waddstr(). If the + strings are too long to fit the window width, the main (centre) string + is truncated. Please note that wrefresh() is NOT called. Also note + the order of rendition values: 1, 3, 2, NOT 1, 2, 3! + + As with center(), the current implementation does NOT handle multibyte + strings correctly. +*/ + +extern int center3 (WINDOW *win, int y, chtype attr1, chtype attr3, + chtype attr2, const char *initial, const char *final, + const char *restrict format, ...) __attribute__((format (printf, 8, 9))); -extern int attrpr (WINDOW *win, int attr, const char *format, ...) - __attribute__((format (printf, 3, 4))); // Input routines