]> granicus.if.org Git - nethack/commitdiff
curses run-time options
authorPatR <rankin@nethack.org>
Tue, 26 Feb 2019 23:16:42 +0000 (15:16 -0800)
committerPatR <rankin@nethack.org>
Tue, 26 Feb 2019 23:16:42 +0000 (15:16 -0800)
This started out as an attempt to document the curses options in the
Guidebook, but I didn't actually get that far.  Instead, integrate
the curses options better via more consistent WC/WC2 usage.  This
prevents 'guicolor' from showing up as a boolean option for non-curses
interface in curses+other binary.

For curses itself, let 'petattr' be set/reset via 'O'.  Also, accept
'Dim' as a possible pet highlight attribute since it already handles
all the other ordinary attributes.  I'm not sure what leftline and
rightline highlighting are supposed to do.  They were missing for
ncurses (or maybe they're misspelled for PDcurses?) but adding them
didn't produce any visible effect (using TERM=xterm-256color on OSX
with default font/character set).

Not addressed:
1) general confusion about compile-time vs run-time option filtering;
2) curses pet highlighting only works if 'color' option is enabled.

include/wincurs.h
src/options.c
win/curses/cursinit.c
win/curses/cursmisc.c
win/curses/cursmisc.h

index cb43f3729a5d921abf32645b065559dce2fc9eec..ddf0264838d830594030a623c797cf37a672d98a 100644 (file)
@@ -45,6 +45,12 @@ extern WINDOW *mapwin, *statuswin, *messagewin;    /* Main windows  */
 # endif
 #endif
 
+#if !defined(A_LEFTLINE) && defined(A_LEFT)
+#define A_LEFTLINE A_LEFT
+#endif
+#if !defined(A_RIGHTLINE) && defined(A_RIGHT)
+#define A_RIGHTLINE A_RIGHT
+#endif
 
 typedef enum orient_type
 {
@@ -158,6 +164,7 @@ extern void curses_rtrim(char *str);
 extern int curses_get_count(int first_digit);
 extern int curses_convert_attr(int attr);
 extern int curses_read_attrs(char *attrs);
+extern char *curses_fmt_attrs(char *);
 extern int curses_convert_keys(int key);
 extern int curses_get_mouse(int *mousex, int *mousey, int *mod);
 
index 64d8d9deac6e844705349ee6b275aea92f1e9311..2c5e463eff661482ebbf6e95f6a9f6b089f7b7a7 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 options.c       $NHDT-Date: 1551138503 2019/02/25 23:48:23 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.355 $ */
+/* NetHack 3.6 options.c       $NHDT-Date: 1551222973 2019/02/26 23:16:13 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.356 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2008. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -29,6 +29,7 @@ NEARDATA struct instance_flags iflags; /* provide linkage */
 
 #ifdef CURSES_GRAPHICS
 extern int curses_read_attrs(char *attrs);
+extern char *curses_fmt_attrs(char *);
 #endif
 
 enum window_option_types {
@@ -131,9 +132,9 @@ static struct Bool_Opt {
     { "flush", (boolean *) 0, FALSE, SET_IN_FILE },
 #endif
     { "force_invmenu", &iflags.force_invmenu, FALSE, SET_IN_GAME },
-    { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE },
+    { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE }, /*WC2*/
     { "goldX", &iflags.goldX, FALSE, SET_IN_GAME },
-    { "guicolor", &iflags.wc2_guicolor, TRUE, SET_IN_GAME},
+    { "guicolor", &iflags.wc2_guicolor, TRUE, SET_IN_GAME}, /*WC2*/
     { "help", &flags.help, TRUE, SET_IN_GAME },
     { "herecmd_menu", &iflags.herecmd_menu, FALSE, SET_IN_GAME },
     { "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/
@@ -209,7 +210,7 @@ static struct Bool_Opt {
     { "showscore", (boolean *) 0, FALSE, SET_IN_FILE },
 #endif
     { "silent", &flags.silent, TRUE, SET_IN_GAME },
-    { "softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE },
+    { "softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE }, /*WC2*/
     { "sortpack", &flags.sortpack, TRUE, SET_IN_GAME },
     { "sparkle", &flags.sparkle, TRUE, SET_IN_GAME },
     { "splash_screen", &iflags.wc_splash_screen, TRUE, DISP_IN_GAME }, /*WC*/
@@ -228,7 +229,7 @@ static struct Bool_Opt {
 #ifdef DEBUG
     { "travel_debug", &iflags.trav_debug, FALSE, SET_IN_WIZGAME }, /*hack.c*/
 #endif
-    { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE },
+    { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE }, /*WC2*/
 #ifdef WIN32
     { "use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME }, /*WC*/
 #else
@@ -243,7 +244,7 @@ static struct Bool_Opt {
     { "whatis_menu", &iflags.getloc_usemenu, FALSE, SET_IN_GAME },
     { "whatis_moveskip", &iflags.getloc_moveskip, FALSE, SET_IN_GAME },
     { "wizweight", &iflags.wizweight, FALSE, SET_IN_WIZGAME },
-    { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME },
+    { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME }, /*WC2*/
 #ifdef ZEROCOMP
     { "zerocomp", &iflags.zerocomp,
 #if defined(COMPRESS) || defined(ZLIB_COMP)
@@ -344,19 +345,18 @@ static struct Comp_Opt {
 #ifdef CHANGE_COLOR
     { "palette",
 #ifndef WIN32
-      "palette (00c/880/-fff is blue/yellow/reverse white)", 15,
-      SET_IN_GAME },
+      "palette (00c/880/-fff is blue/yellow/reverse white)", 15, SET_IN_GAME
 #else
-      "palette (adjust an RGB color in palette (color-R-G-B)", 15,
-      SET_IN_FILE },
+      "palette (adjust an RGB color in palette (color-R-G-B)", 15, SET_IN_FILE
 #endif
+    },
 #if defined(MAC)
     { "hicolor", "same as palette, only order is reversed", 15, SET_IN_FILE },
 #endif
 #endif
     { "paranoid_confirmation", "extra prompting in certain situations", 28,
       SET_IN_GAME },
-    { "petattr",  "attributes for highlighting pets", 12, SET_IN_FILE },
+    { "petattr",  "attributes for highlighting pets", 88, SET_IN_GAME },
     { "pettype", "your preferred initial pet type", 4, DISP_IN_GAME },
     { "pickup_burden", "maximum burden picked up before prompt", 20,
       SET_IN_GAME },
@@ -409,6 +409,9 @@ static struct Comp_Opt {
 #endif
     { "suppress_alert", "suppress alerts about version-specific features", 8,
       SET_IN_GAME },
+    /* term_cols,term_rows -> WC2_TERM_SIZE (6: room to format 1..32767) */
+    { "term_cols", "number of columns", 6, SET_IN_FILE }, /*WC2*/
+    { "term_rows", "number of rows", 6, SET_IN_FILE }, /*WC2*/
     { "tile_width", "width of tiles", 20, DISP_IN_GAME },   /*WC*/
     { "tile_height", "height of tiles", 20, DISP_IN_GAME }, /*WC*/
     { "tile_file", "name of tile file", 70, DISP_IN_GAME }, /*WC*/
@@ -430,6 +433,7 @@ static struct Comp_Opt {
     { "whatis_filter",
       "filter coordinate locations when targeting next or previous",
       1, SET_IN_GAME },
+    { "windowborders", "1 (on), 2 (off), 3 (auto)", 9, DISP_IN_GAME }, /*WC2*/
     { "windowcolors", "the foreground/background colors of windows", /*WC*/
       80, DISP_IN_GAME },
     { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
@@ -3325,6 +3329,7 @@ boolean tinitial, tfrom_file;
         return retval;
     }
 #endif /* VIDEOSHADES */
+
 #ifdef MSDOS
 #ifdef NO_TERMS
     /* video:string -- must be after longer tests */
@@ -3447,8 +3452,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else {
 #if defined(WIN32)
+        } else {
             op = string_for_opt(opts, 0);
             if (!op)
                 return FALSE;
@@ -3593,29 +3598,34 @@ boolean tinitial, tfrom_file;
         }
         return retval;
     }
+
 #ifdef CURSES_GRAPHICS
     /* WINCAP2
-     * term_cols:amount */
+     * term_cols:amount or term_rows:amount */
     fullname = "term_cols";
-    if (match_optname(opts, fullname, sizeof "term_cols" - 1, TRUE)) {
-        op = string_for_opt(opts, negated);
-        iflags.wc2_term_cols = atoi(op);
-        if (negated) {
-            bad_negation(fullname, FALSE);
-            return FALSE;
-        }
-        return retval;
-    }
+    if (match_optname(opts, fullname, 8, TRUE)
+        /* alternate spelling */
+        || match_optname(opts, "term_columns", 9, TRUE)
+        /* different option but identical handlng */
+        || (fullname = "term_rows", match_optname(opts, fullname, 8, TRUE))) {
+        long ltmp;
 
-    /* WINCAP2
-     * term_rows:amount */
-    fullname = "term_rows";
-    if (match_optname(opts, fullname, sizeof "term_rows" - 1, TRUE)) {
         op = string_for_opt(opts, negated);
-        iflags.wc2_term_rows = atoi(op);
+        ltmp = atol(op);
         if (negated) {
             bad_negation(fullname, FALSE);
-            return FALSE;
+            retval = FALSE;
+
+        /* this just checks atol() sanity, not logical window size sanity */
+        } else if (ltmp <= 0L || ltmp >= (long) LARGEST_INT) {
+            config_error_add("Invalid %s: %ld", fullname, ltmp);
+            retval = FALSE;
+
+        } else {
+            if (!strcmp(fullname, "term_rows"))
+                iflags.wc2_term_rows = (int) ltmp;
+            else /* !strcmp(fullname, "term_cols") */
+                iflags.wc2_term_cols = (int) ltmp;
         }
         return retval;
     }
@@ -3625,22 +3635,31 @@ boolean tinitial, tfrom_file;
     fullname = "petattr";
     if (match_optname(opts, fullname, sizeof "petattr" - 1, TRUE)) {
         op = string_for_opt(opts, negated);
-        if (op && !negated) {
+        if (op && negated) {
+            bad_negation(fullname, TRUE);
+            retval = FALSE;
+        } else if (op) {
 #ifdef CURSES_GRAPHICS
-            iflags.wc2_petattr = curses_read_attrs(op);
-            if (!curses_read_attrs(op)) {
+            int itmp = curses_read_attrs(op);
+
+            if (itmp == -1) {
                 config_error_add("Unknown %s parameter '%s'", fullname, opts);
-                return FALSE;
-            }
+                retval = FALSE;
+            } else
+                iflags.wc2_petattr = itmp;
 #else
             /* non-curses windowports will not use this flag anyway
              * but the above will not compile if we don't have curses.
              * Just set it to a sensible default: */
-            iflags.wc2_petattr = ATR_INVERSE
+            iflags.wc2_petattr = ATR_INVERSE;
 #endif
         } else if (negated) {
-            bad_negation(fullname, TRUE);
-            return FALSE;
+            iflags.wc2_petattr = ATR_NONE;
+        }
+        if (retval) {
+            iflags.hilite_pet = (iflags.wc2_petattr != ATR_NONE);
+            if (!initial)
+                need_redraw = TRUE;
         }
         return retval;
     }
@@ -3648,28 +3667,31 @@ boolean tinitial, tfrom_file;
     /* WINCAP2
      * windowborders:n */
     fullname = "windowborders";
-    if (match_optname(opts, fullname, sizeof "windowborders" - 1, TRUE)) {
+    if (match_optname(opts, fullname, 10, TRUE)) {
         op = string_for_opt(opts, negated);
         if (negated && op) {
             bad_negation(fullname, TRUE);
-            return FALSE;
+            retval = FALSE;
         } else {
+            int itmp;
+
             if (negated)
-                iflags.wc2_windowborders = 2; /* Off */
+                itmp = 2; /* Off */
             else if (!op)
-                iflags.wc2_windowborders = 1; /* On */
-            else    /* Value supplied */
-                iflags.wc2_windowborders = atoi(op);
-            if ((iflags.wc2_windowborders > 3)
-                || (iflags.wc2_windowborders < 1)) {
-                    iflags.wc2_windowborders = 0;
-                    config_error_add("Badoption - windowborders %s.", opts);
-                    return FALSE;
+                itmp = 1; /* On */
+            else    /* Value supplied; expect 1 (on), 2 (off), or 3 (auto) */
+                itmp = atoi(op);
+
+            if (itmp < 1 || itmp > 3) {
+                config_error_add("Invalid %s: %s.", fullname, opts);
+                retval = FALSE;
+            } else {
+                iflags.wc2_windowborders = itmp;
             }
         }
         return retval;
     }
-#endif
+#endif /* CURSES_GRAPHICS */
 
     /* menustyle:traditional or combination or full or partial */
     fullname = "menustyle";
@@ -5592,6 +5614,18 @@ char *buf;
             if (flags.paranoia_bits & paranoia[i].flagmask)
                 Sprintf(eos(tmpbuf), " %s", paranoia[i].argname);
         Strcpy(buf, tmpbuf[0] ? &tmpbuf[1] : "none");
+    } else if (!strcmp(optname, "petattr")) {
+#ifdef CURSES_GRAPHICS
+        if (WINDOWPORT("curses")) {
+            char tmpbuf[QBUFSZ];
+
+            Strcpy(buf, curses_fmt_attrs(tmpbuf));
+        } else
+#endif
+        if (iflags.wc2_petattr != 0)
+            Sprintf(buf, "0x%08x", iflags.wc2_petattr);
+        else
+            Strcpy(buf, defopt);
     } else if (!strcmp(optname, "pettype")) {
         Sprintf(buf, "%s", (preferred_pet == 'c') ? "cat"
                            : (preferred_pet == 'd') ? "dog"
@@ -5674,7 +5708,6 @@ char *buf;
                 symset[PRIMARY].name ? symset[PRIMARY].name : "default");
         if (currentgraphics == PRIMARY && symset[PRIMARY].name)
             Strcat(buf, ", active");
-#ifdef CURSES_GRAPHICS
     } else if (!strcmp(optname, "term_cols")) {
         if (iflags.wc2_term_cols)
             Sprintf(buf, "%d", iflags.wc2_term_cols);
@@ -5682,10 +5715,9 @@ char *buf;
             Strcpy(buf, defopt);
     } else if (!strcmp(optname, "term_rows")) {
         if (iflags.wc2_term_rows)
-            Sprintf(buf, "%d",iflags.wc2_term_rows);
+            Sprintf(buf, "%d", iflags.wc2_term_rows);
         else
             Strcpy(buf, defopt);
-#endif
     } else if (!strcmp(optname, "tile_file")) {
         Sprintf(buf, "%s",
                 iflags.wc_tile_file ? iflags.wc_tile_file : defopt);
@@ -6433,9 +6465,11 @@ static struct wc_Opt wc2_options[] = {
     { "status hilite rules", WC2_HILITE_STATUS },
     /* statushilites doesn't have its own bit */
     { "statushilites", WC2_HILITE_STATUS },
-#ifdef CURSES_GRAPHICS
-    {"windowborders", WC2_WINDOWBORDERS},
-#endif
+    { "term_cols", WC2_TERM_SIZE },
+    { "term_rows", WC2_TERM_SIZE },
+    { "petattr", WC2_PETATTR },
+    { "guicolor", WC2_GUICOLOR },
+    { "windowborders", WC2_WINDOWBORDERS },
     { (char *) 0, 0L }
 };
 
index 5f53df4edfbb46865df30c6584da073147493faa..1cdc62a185b2a85b15072804f402be2b5cb37bf9 100644 (file)
@@ -835,11 +835,15 @@ curses_init_options()
         iflags.wc2_windowborders = 3;   /* Set to auto if not specified */
     }
 
-    if (!iflags.wc2_petattr) {
-        iflags.wc2_petattr = A_REVERSE;
-    } else { /* Pet attribute specified, so hilite_pet should be true */
-
+    /* fix up pet highlighting */
+    if (iflags.wc2_petattr == -1) /* shouldn't happen */
+        iflags.wc2_petattr = A_NORMAL;
+    if (iflags.wc2_petattr != A_NORMAL) {
+        /* Pet attribute specified, so hilite_pet should be true */
         iflags.hilite_pet = TRUE;
+    } else if (iflags.hilite_pet) {
+        /* pet highlighting specified, so don't leave petattr at A_NORMAL */
+        iflags.wc2_petattr = A_REVERSE;
     }
 
 #ifdef NCURSES_MOUSE_VERSION
index b4b3764d7061d10d44042a865e398409d1f8cb4d..63bf2e03d55bf53099288606002f0b938fcf70e3 100644 (file)
@@ -47,7 +47,7 @@ curses_read_char()
     ch = curses_convert_keys(ch);
 
     if (ch == 0) {
-        ch = '\033';          /* map NUL to ESC since nethack doesn't expect NUL */
+        ch = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */
     }
 #if defined(ALT_0) && defined(ALT_9)    /* PDCurses, maybe others */
     if ((ch >= ALT_0) && (ch <= ALT_9)) {
@@ -66,11 +66,11 @@ curses_read_char()
 #ifdef KEY_RESIZE
     /* Handle resize events via get_nh_event, not this code */
     if (ch == KEY_RESIZE) {
-        ch = '\033';          /* NetHack doesn't know what to do with KEY_RESIZE */
+        ch = '\033'; /* NetHack doesn't know what to do with KEY_RESIZE */
     }
 #endif
 
-    if (counting && !isdigit(ch)) {     /* Dismiss count window if necissary */
+    if (counting && !isdigit(ch)) { /* Dismiss count window if necissary */
         curses_count_window(NULL);
         curses_refresh_nethack_windows();
     }
@@ -249,7 +249,7 @@ curses_num_lines(const char *str, int width)
         if (last_space == 0) {  /* No spaces found */
             last_space = count - 1;
         }
-        for (count = (last_space + 1); (size_t) count < strlen(substr); count++) {
+        for (count = (last_space + 1); count < (int) strlen(substr); count++) {
             tmpstr[count - (last_space + 1)] = substr[count];
         }
         tmpstr[count - (last_space + 1)] = '\0';
@@ -389,7 +389,7 @@ curses_str_remainder(const char *str, int width, int line_num)
         if (substr[count] == '\0') {
             break;
         }
-        for (count = (last_space + 1); (size_t) count < strlen(substr); count++) {
+        for (count = (last_space + 1); count < (int) strlen(substr); count++) {
             tmpstr[count - (last_space + 1)] = substr[count];
         }
         tmpstr[count - (last_space + 1)] = '\0';
@@ -682,44 +682,87 @@ curses_convert_attr(int attr)
 
 
 /* Map letter attributes from a string to bitmask.  Return mask on
-success, or 0 if not found */
+   success (might be 0), or -1 if not found. */
 
 int
 curses_read_attrs(char *attrs)
 {
     int retattr = 0;
 
-    if (strchr(attrs, 'b') || strchr(attrs, 'B')) {
-        retattr = retattr | A_BOLD;
-    }
-    if (strchr(attrs, 'i') || strchr(attrs, 'I')) {
-        retattr = retattr | A_REVERSE;
-    }
-    if (strchr(attrs, 'u') || strchr(attrs, 'U')) {
-        retattr = retattr | A_UNDERLINE;
-    }
-    if (strchr(attrs, 'k') || strchr(attrs, 'K')) {
-        retattr = retattr | A_BLINK;
-    }
+    if (!attrs || !*attrs)
+        return A_NORMAL;
+
+    if (strchr(attrs, 'b') || strchr(attrs, 'B'))
+        retattr |= A_BOLD;
+    if (strchr(attrs, 'i') || strchr(attrs, 'I')) /* inverse */
+        retattr |= A_REVERSE;
+    if (strchr(attrs, 'u') || strchr(attrs, 'U'))
+        retattr |= A_UNDERLINE;
+    if (strchr(attrs, 'k') || strchr(attrs, 'K'))
+        retattr |= A_BLINK;
+    if (strchr(attrs, 'd') || strchr(attrs, 'D'))
+        retattr |= A_DIM;
 #ifdef A_ITALIC
-    if (strchr(attrs, 't') || strchr(attrs, 'T')) {
-        retattr = retattr | A_ITALIC;
-    }
+    if (strchr(attrs, 't') || strchr(attrs, 'T'))
+        retattr |= A_ITALIC;
+#endif
+#ifdef A_LEFTLINE
+    if (strchr(attrs, 'l') || strchr(attrs, 'L'))
+        retattr |= A_LEFTLINE;
 #endif
 #ifdef A_RIGHTLINE
-    if (strchr(attrs, 'r') || strchr(attrs, 'R')) {
-        retattr = retattr | A_RIGHTLINE;
-    }
+    if (strchr(attrs, 'r') || strchr(attrs, 'R'))
+        retattr |= A_RIGHTLINE;
 #endif
-#ifdef A_LEFTLINE
-    if (strchr(attrs, 'l') || strchr(attrs, 'L')) {
-        retattr = retattr | A_LEFTLINE;
+    if (retattr == 0) {
+        /* still default; check for none/normal */
+        if (strchr(attrs, 'n') || strchr(attrs, 'N'))
+            retattr = A_NORMAL;
+        else
+            retattr = -1; /* error */
     }
-#endif
-
     return retattr;
 }
 
+/* format iflags.wc2_petattr into "+a+b..." for set bits a, b, ...
+   (used by core's 'O' command; return value points past leading '+') */
+char *
+curses_fmt_attrs(outbuf)
+char *outbuf;
+{
+    int attr = iflags.wc2_petattr;
+
+    outbuf[0] = '\0';
+    if (attr == A_NORMAL) {
+        Strcpy(outbuf, "+N(None)");
+    } else {
+        if (attr & A_BOLD)
+            Strcat(outbuf, "+B(Bold)");
+        if (attr & A_REVERSE)
+            Strcat(outbuf, "+I(Inverse)");
+        if (attr & A_UNDERLINE)
+            Strcat(outbuf, "+U(Underline)");
+        if (attr & A_BLINK)
+            Strcat(outbuf, "+K(blinK)");
+        if (attr & A_DIM)
+            Strcat(outbuf, "+D(Dim)");
+#ifdef A_ITALIC
+        if (attr & A_ITALIC)
+            Strcat(outbuf, "+T(iTalic)");
+#endif
+#ifdef A_LEFTLINE
+        if (attr & A_LEFTLINE)
+            Strcat(outbuf, "+L(Left line)");
+#endif
+#ifdef A_RIGHTLINE
+        if (attr & A_RIGHTLINE)
+            Strcat(outbuf, "+R(Right line)");
+#endif
+    }
+    if (!*outbuf)
+        Sprintf(outbuf, "+unknown [%d]", attr);
+    return &outbuf[1];
+}
 
 /* Convert special keys into values that NetHack can understand.
 Currently this is limited to arrow keys, but this may be expanded. */
@@ -827,7 +870,7 @@ curses_get_mouse(int *mousex, int *mousey, int *mod)
 #ifdef NCURSES_MOUSE_VERSION
     MEVENT event;
 
-    if (getmouse(&event) == OK) {       /* When the user clicks left mouse button */
+    if (getmouse(&event) == OK) { /* When the user clicks left mouse button */
         if (event.bstate & BUTTON1_CLICKED) {
             /* See if coords are in map window & convert coords */
             if (wmouse_trafo(mapwin, &event.y, &event.x, TRUE)) {
index 36490126745b6f51a86ad6ef21b26a3c4b1e77d9..392d67d11cb0a3e727e090fc45e33b0125d092d5 100644 (file)
@@ -27,6 +27,7 @@ void curses_rtrim(char *str);
 int curses_get_count(int first_digit);
 int curses_convert_attr(int attr);
 int curses_read_attrs(char *attrs);
+char *curses_fmt_attrs(char *);
 int curses_convert_keys(int key);
 int curses_get_mouse(int *mousex, int *mousey, int *mod);