[PATCH 16/16] test/move_field.c: Add help text.

"G. Branden Robinson" <[email protected]>
Newsgroups gmane.comp.lib.ncurses.bugs
Message-ID <20260815122214.he2oupokef75k6pf@illithid>
* test/move_field.c: Add new global WINDOW pointer `win_help` and const
  char pointer `main_help_text`.
  (rip_help): New function stores the WINDOW pointer for the help window
  created by initscr(3).
  (configure_help): New function sets up the help window's background
  but does not populate its text.
  (update_help): New function writes string in argument to help window.
  (show_status): Allocate a buffer on the stack to hold the text of the
  help message used while moving a field.  Maintain the existing method
  of populating the line if `HAVE_RIPOFFLINE` is false; populate and
  refresh the ripped-off help window otherwise.
  (do_demo): When the user leaves field-moving move, maintain the
  existing method of clearing the last line of the (`stdscr`) window if
  `HAVE_RIPOFFLINE` is false; re-populate the ripped-off help window
  with the "main help text" and refresh it otherwise.
  (main): Allocate a buffer on the stack to hold the "main help text".
  Call ripoffline(3) to reserve a help window.  Once curses and
  color pairs are set up, call `configure_help()`.  If `HAVE_RIPOFFLINE`
  is true, populate the message and write it to the ripped-off help
  window with a strdup(3)ed copy of the message on the heap to
  paranoiacally avoid optimizer stack shenanigans.  Free that heap
  memory before exiting.
---
 test/move_field.c | 74 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 69 insertions(+), 5 deletions(-)

diff --git a/test/move_field.c b/test/move_field.c
index 7f92bcc2f..db36580fe 100644
--- a/test/move_field.c
+++ b/test/move_field.c
@@ -46,6 +46,10 @@
 static char empty[] = "";
 static FIELD *all_fields[MAX_FIELDS];
 static unsigned num_fields;
+#if HAVE_RIPOFFLINE
+WINDOW *win_help = NULL;
+const char *main_help_text = NULL;
+#endif
 /* *INDENT-OFF* */
 static struct {
     int code;
@@ -290,20 +294,59 @@ copy_fields(FIELD **source, size_t length)
     return target;
 }
 
+#if HAVE_RIPOFFLINE
+static int
+rip_help(WINDOW *win, int cols)
+{
+    win_help = win;
+    return OK;
+}
+
+/*
+ * We can't do this stuff in rip_help() because colors aren't yet set up
+ * when initscr() calls it.
+ */
+static void
+configure_help(WINDOW *win)
+{
+    wbkgd(win, (chtype) COLOR_PAIR(1));
+    werase(win);
+    wmove(win, 0, 0);
+    wnoutrefresh(win);
+}
+
+static void
+update_help(WINDOW *win, const char *message)
+{
+    werase(win);
+    wprintw(win, message);
+    wnoutrefresh(win);
+}
+#endif
+
 /* display a status message to show what's happening */
 static void
 show_status(NCURSES_CONST FORM *form, NCURSES_CONST FIELD *field)
 {
     NCURSES_CONST WINDOW *sub = form_sub(form);
     int currow, curcol;
+    const size_t bufsz = 512; /* maximum # columns ncurses supports */
+    char buf[bufsz];
 
+    memset(buf, 0, bufsz);
     getyx(stdscr, currow, curcol);
-    mvprintw(LINES - 1, 0,
-	     "Field at [%d,%d].  Press %s to quit moving.",
-	     getbegy(sub) + form_field_row(field),
-	     getbegx(sub) + form_field_col(field),
-	     keyname(DO_DEMO));
+    (void) snprintf(buf, bufsz,
+		    "Field at [%d,%d].  Press %s to quit moving.",
+		    getbegy(sub) + form_field_row(field),
+		    getbegx(sub) + form_field_col(field),
+		    keyname(DO_DEMO));
+#if HAVE_RIPOFFLINE
+    update_help(win_help, buf);
+    wrefresh(win_help);
+#else
+    mvaddstr(LINES - 1, 0, buf);
     clrtobot();
+#endif
     move(currow, curcol);
     refresh();
 }
@@ -411,8 +454,12 @@ do_demo(FORM *form)
 		}
 
 		/* cleanup */
+#if HAVE_RIPOFFLINE
+		update_help(win_help, main_help_text);
+#else
 		move(LINES - 1, 0);
 		clrtobot();
+#endif
 		move(currow, curcol);
 		refresh();
 	    }
@@ -526,6 +573,8 @@ VERSION_COMMON()
 int
 main(int argc, char *argv[])
 {
+    const size_t bufsz = 512; /* maximum # columns ncurses supports */
+    char buf[bufsz];
     int ch;
 
     while ((ch = getopt(argc, argv, OPTS_COMMON)) != -1) {
@@ -540,6 +589,9 @@ main(int argc, char *argv[])
 
     setlocale(LC_ALL, "");
 
+#if HAVE_RIPOFFLINE
+    ripoffline(-1, rip_help);
+#endif
     initscr();
     cbreak();
     noecho();
@@ -557,9 +609,21 @@ main(int argc, char *argv[])
 	refresh();
     }
 
+#if HAVE_RIPOFFLINE
+    configure_help(win_help);
+    memset(buf, 0, bufsz);
+    (void) snprintf(buf, bufsz,
+		    "Press F1 for help, %s to move field,"
+		    " or ^Q to quit.",
+		    keyname(DO_DEMO));
+    main_help_text = strdup(buf); // don't point to stack memory
+    update_help(win_help, buf);
+    wrefresh(win_help);
+#endif /* HAVE_RIPOFFLINE */
     demo_forms();
 
     endwin();
+    free((char *)main_help_text);
     ExitProgram(EXIT_SUCCESS);
 }
 
-- 
2.30.2
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEh3PWHWjjDgcrENwa0Z6cfXEmbc4FAmqAWfYACgkQ0Z6cfXEm
bc47eRAAlhJRD8M4Daho7TlBiOz5FY51WS4eOYGL5O96jCAPbPvt/b9TogFJPt+s
VwIub8asZTLUrVALzZLCFKTHocXVHMccltl8tYT+jtz/LB/TmCI5vScrs5bBkxPN
Qjb8w5LbD3xD3YLEMnCT6Bc3k5wmby5garRKz3RyagVFatcnpch4v4s2waPwYW+7
nW75SDsaigWoopkps2zXVaJvtBmAxZEoqK1dJQLSIVtUzDUPsxO/Ga59qzChSKnv
OMnBmvQLWfKKlxGSmLLScON0BFBQmuQop8pKA7MkTCfGPabpV3WcNBHCjzZ24oRL
YItpTM4fTWQ1w9Hvzg/Fug+IlXNlaXFMI7volaMlqJjWqUsczLxJIDEfnOd2RSez
YTfd7ms55yX6fJNMSUzjjM6wSsi2hQjaPi4fO4ICe+TTEmn+HWZ46Jr5Q0zskalb
W7sXLn3Nnx8su/M/WqReBaKX1oq3/1RCeBGtY2t5OpytwU6E4nQ0vV6dchQ+3yGZ
oCb77kJTGOHLlBBxtx018dWR+LWQXqhrOGE+RiF9I7GWvGyuViQjs6/ip8X95XW4
BsjrzYuOdtTD1vMf5UFKVk2gU2Llg0lrm5hRKKkUZWmqzqtSbvZNn1VJy3t+UXcZ
auP0iGQZoL7DBiuiQWl8cwmVdBjxn64nDkHvMvGjZBXMOfDlkiU=
=wNYm
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.