gtx: use getmaxyx() with sensible fallbacks
authorBrandon S Allbery <ballbery@sinenomine.net>
Tue, 24 Nov 2015 21:39:02 +0000 (16:39 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Thu, 3 Dec 2015 04:26:50 +0000 (23:26 -0500)
configure now checks for the standard getmaxyx() macro; failing that,
it looks for the older but pre-standardization getmaxx() and getmaxy(),
then falls back to the 4.2BSD curses _maxx and _maxy fields; if all
else fails, gtx building is disabled.

gtx now defines getmaxyx() itself if necessary, based on the above.

This also fixes a bug in gtx with all ncurses versions > 1.8.0 on
platforms other than NetBSD and OS X: gtx was using the _maxx and
_maxy fields, which starting with ncurses 1.8.1 were off by 1 from
the expected values. As such, behavior of scout and/or afsmonitor
may change on most ncurses-using platforms.

Change-Id: I49778e87adacef2598f0965e09538dfc3d840dcc
Reviewed-on: http://gerrit.openafs.org/12107
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Chas Williams <3chas3@gmail.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

acinclude.m4
src/cf/curses.m4 [new file with mode: 0644]
src/gtx/curseswindows.c
src/gtx/gtxcurseswin.h

index abc6062..3f0d297 100644 (file)
@@ -76,9 +76,6 @@ AC_ARG_WITH([afs-sysname],
 ])
 
 dnl General feature options.
-AC_ARG_ENABLE([gtx],
-    [AS_HELP_STRING([--disable-gtx], [disable gtx curses-based terminal tools])])
-
 AC_ARG_ENABLE([namei-fileserver],
     [AS_HELP_STRING([--enable-namei-fileserver],
        [force compilation of namei fileserver in preference to inode
@@ -1554,17 +1551,6 @@ AC_CHECK_TYPES([fsblkcnt_t],,,[
 dnl see what struct stat has for timestamps
 AC_CHECK_MEMBERS([struct stat.st_ctimespec, struct stat.st_ctimensec])
 
-dnl check for curses-lib
-AS_IF([test "x$enable_gtx" != "xno"],
-      [save_LIBS=$LIBS
-      AC_CHECK_LIB( [ncurses], [setupterm],
-      [LIB_curses=-lncurses],
-        [AC_CHECK_LIB([Hcurses], [setupterm], [LIB_curses=-lHcurses],
-          [AC_CHECK_LIB([curses], [setupterm], [LIB_curses=-lcurses])])
-      ])
-      LIBS=$save_LIBS
-      AC_SUBST(LIB_curses)])
-       
 OPENAFS_TEST_PACKAGE(libintl,[#include <libintl.h>],[-lintl],,,INTL)
 
 if test "$enable_debug_locks" = yes; then
@@ -1628,6 +1614,7 @@ AC_CHECK_FUNCS([ \
 
 OPENAFS_ROKEN()
 OPENAFS_HCRYPTO()
+OPENAFS_CURSES()
 OPENAFS_C_ATTRIBUTE()
 
 dnl Functions that Heimdal's libroken provides, but that we
diff --git a/src/cf/curses.m4 b/src/cf/curses.m4
new file mode 100644 (file)
index 0000000..a0cdc60
--- /dev/null
@@ -0,0 +1,94 @@
+dnl _OPENAFS_CURSES_HEADERS
+dnl abstracting out the preprocessor gunk to #include curses
+AC_DEFUN([_OPENAFS_CURSES_HEADERS],[
+#if defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
+])
+
+dnl OPENAFS_CURSES_LIB([ACTION-IF-SUCCESS], [ACTION_IF_FAILURE])
+dnl check for a working curses library and set $LIB_curses if so
+AC_DEFUN([OPENAFS_CURSES_LIB],
+[AC_CACHE_VAL([openafs_cv_curses_lib],
+   [save_LIBS="$LIBS"
+    openafs_cv_curses_lib=
+    AC_CHECK_LIB([ncurses], [initscr], [openafs_cv_curses_lib=-lncurses])
+    AS_IF([test "x$openafs_cv_curses_lib" = x],
+         [AC_CHECK_LIB([Hcurses], [initscr], [openafs_cv_curses_lib=-lHcurses])])
+    AS_IF([test "x$openafs_cv_curses_lib" = x],
+         [AC_CHECK_LIB([curses], [initscr], [openafs_cv_curses_lib=-lcurses])])
+    LIBS="$save_LIBS"])
+ LIB_curses="$openafs_cv_curses_lib"
+ AC_SUBST(LIB_curses)
+ AC_MSG_NOTICE([checking for curses library... ${openafs_cv_curses_lib:-none}])
+ AS_IF([test "x$openafs_cv_curses_lib" != x], [$1], [$2])])
+
+dnl _OPENAFS_CURSES_GETMAXYX_XTI([ACTION-IF-SUCCESS], [ACTION_IF_FAILURE])
+dnl test for XTI-standard getmaxyx()
+AC_DEFUN([_OPENAFS_CURSES_GETMAXYX_XTI],
+[dnl paranoid check because of complex macros in various curses impls
+ AC_CACHE_CHECK([getmaxyx macro], [openafs_cv_curses_getmaxyx],
+   [save_LIBS="$LIBS"
+    LIBS="$LIBS $LIB_curses"
+    AC_TRY_LINK(_OPENAFS_CURSES_HEADERS,
+               [int mx, my; initscr(); getmaxyx(stdscr, my, mx); endwin();],
+               [openafs_cv_curses_getmaxyx=yes],
+               [openafs_cv_curses_getmaxyx=no])
+    LIBS="$save_LIBS"])
+ AS_IF([test x"$openafs_cv_curses_getmaxyx" = xyes],
+       [AC_DEFINE(HAVE_GETMAXYX, 1,
+                 [define if your curses has the getmaxyx() macro])
+       $1],
+       [$2])])
+
+dnl _OPENAFS_CURSES_GETMAXYX_BSD43([ACTION-IF-SUCCESS], [ACTION_IF_FAILURE])
+dnl test for getmaxx() and getmaxy() as from later BSD curses
+AC_DEFUN([_OPENAFS_CURSES_GETMAXYX_BSD43],
+[OPENAFS_CURSES_LIB
+ save_LIBS="$LIBS"
+ LIBS="$LIBS $LIB_curses"
+ _openafs_curses_bsd43=yes
+ dnl possibly this may need to be done as above in some cases?
+ AC_CHECK_FUNCS([getmaxx getmaxy], [], [_openafs_curses_bsd43=no])
+ LIBS="$save_LIBS"
+ AS_IF([$_openafs_curses_bsd43 = yes], [$1], [$2])])
+
+dnl _OPENAFS_CURSES_GETMAXYX_BSDVI([ACTION-IF-SUCCESS], [ACTION_IF_FAILURE])
+dnl test for getmaxx() and getmaxy() as from BSD curses as bodily ripped
+dnl out of the original vi sources
+AC_DEFUN([_OPENAFS_CURSES_GETMAXYX_BSDVI],
+[OPENAFS_CURSES_LIB
+ save_LIBS="$LIBS"
+ LIBS="$LIBS $LIB_curses"
+ _openafs_curses_bsdvi=yes
+ AC_CHECK_MEMBERS([WINDOW._maxx WINDOW._maxy], [], [_openafs_curses_bsdvi=no],
+                 _OPENAFS_CURSES_HEADERS)
+ LIBS="$save_LIBS"
+ AS_IF([$_openafs_curses_bsdvi = yes], [$1], [$2])])
+
+dnl OPENAFS_CURSES_WINDOW_EXTENTS([ACTION-IF-SUCCESS], [ACTION_IF_FAILURE])
+dnl check for standard getmaxyx macro. failing that, try the
+dnl older getmaxx and getmaxy functions/macros; failing those,
+dnl try the 4.2BSD _maxx and _maxy fields
+AC_DEFUN([OPENAFS_CURSES_WINDOW_EXTENTS],
+[OPENAFS_CURSES_LIB
+ openafs_curses_extent=none
+ _OPENAFS_CURSES_GETMAXYX_XTI([openafs_curses_extent=xti])
+ AS_IF([test $openafs_curses_extent = none],
+       [_OPENAFS_CURSES_GETMAXYX_BSD43([openafs_curses_extent=bsd])])
+ AS_IF([test $openafs_curses_extent = none],
+       [_OPENAFS_CURSES_GETMAXYX_BSDVI([openafs_curses_extent=vi])],)
+ AS_IF([test $openafs_curses_extent != none], [$1], [$2])])
+
+dnl The top level curses group
+AC_DEFUN([OPENAFS_CURSES],
+[AC_ARG_ENABLE([gtx],
+    [AS_HELP_STRING([--disable-gtx], [disable gtx curses-based terminal tools])])
+ AS_IF([test "x$enable_gtx" != "xno"],
+       [OPENAFS_CURSES_LIB([], [enable_gtx=no])])
+ AS_IF([test "x$enable_gtx" != "xno"],
+       [OPENAFS_CURSES_WINDOW_EXTENTS([], [enable_gtx=no])])])
index 89d94f3..d184f6d 100644 (file)
@@ -761,13 +761,7 @@ gator_cursesgwin_getdimensions(struct gwin *gwp, struct gwin_sizeparams *aparms)
     struct gator_cursesgwin *cwp;      /*Curses-specific data */
 
     cwp = (struct gator_cursesgwin *)(gwp->w_data);
-#if defined(AFS_NBSD_ENV) || defined(AFS_DARWIN100_ENV)
-    aparms->maxx = getmaxx(cwp->wp);
-    aparms->maxy = getmaxy(cwp->wp);
-#else
-    aparms->maxx = cwp->wp->_maxx;
-    aparms->maxy = cwp->wp->_maxy;
-#endif
+    getmaxyx(cwp->wp, aparms->maxy, aparms->maxx);
 
     return (0);
 
index be88e07..e626a0f 100644 (file)
 # include <curses.h>
 #endif
 
+#ifndef HAVE_GETMAXYX
+#  if defined(HAVE_GETMAXY) && defined(HAVE_GETMAXX)
+#    define getmaxyx(w,y,x) do {(y) = getmaxy(w); (x) = getmaxx(w);} while (0)
+#  else
+#    define getmaxyx(w,y,x) do {(y) = (w)->_maxy; (x) = (w)->_maxx;} while (0)
+#  endif
+#endif
+
 /*Value for gwin w_type field*/
 #define        GATOR_WIN_CURSES    2