]> git.draconx.ca Git - dxcommon.git/blobdiff - m4/curses-compat.m4
Add some curses-related feature tests.
[dxcommon.git] / m4 / curses-compat.m4
diff --git a/m4/curses-compat.m4 b/m4/curses-compat.m4
new file mode 100644 (file)
index 0000000..c445a67
--- /dev/null
@@ -0,0 +1,93 @@
+dnl Copyright © 2022 Nick Bowler
+dnl
+dnl Macros for probing specific curses library behaviour.
+dnl
+dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+dnl This is free software: you are free to do what the fuck you want to.
+dnl There is NO WARRANTY, to the extent permitted by law.
+
+dnl DX_CHECK_CURSES_FUNC(function, [args], [prologue])
+dnl
+dnl Simple yes/no check for whether the curses library provides the specified
+dnl function.  If it does, the macro HAVE_CURSES_func macro is defined to 1,
+dnl where func is the specified function name in capital letters.  The cache
+dnl variable dx_cv_curses_have_func is set to "yes" if the function is
+dnl detected, or "no" otherwise.
+dnl
+dnl The second argument is the argument list (without its enclosing
+dnl parentheses) used to construct a syntactically valid function call.
+dnl Typically most arguments can simply be 0.
+dnl
+dnl The third argument is additional C code to be placed before the function
+dnl call within main.  This can include declarations and statements.
+AC_DEFUN([DX_CHECK_CURSES_FUNC],
+[_DX_CURSES_LINKTEST([supports $1], [$1], [$3; $1($2)])])
+
+dnl DX_CHECK_CURSES_GETMOUSE_NCURSES
+dnl
+dnl Check if the curses library provides the getmouse function with an
+dnl ncurses-compatible interface.  Some other curses libraries also have
+dnl a function named getmouse but with a totally different interface.
+dnl
+dnl If so, the macro HAVE_CURSES_GETMOUSE_NCURSES is defined to 1 and the
+dnl cache variable dx_cv_curses_have_getmouse_ncurses is set to "yes".
+dnl Otherwise the cache variable is set to "no".
+AC_DEFUN([DX_CHECK_CURSES_GETMOUSE_NCURSES],
+[_DX_CURSES_LINKTEST([has ncurses-like getmouse], [getmouse_ncurses],
+[MEVENT ev; { extern int getmouse(MEVENT *); getmouse(&ev); } getmouse(&ev)])])
+
+dnl DX_CHECK_CURSES_MOUSE_SUPPORT
+dnl
+dnl Probe a set of mouse-related curses functions to figure out what is
+dnl needed for basic mouse support.  This is implemented using the preceding
+dnl macros and sets the same outputs.
+dnl
+dnl Additionally, the HAVE_CURSES_MOUSE_SUPPORT macro is defined to 1 if:
+dnl
+dnl   - one of mouse_set or mousemask is found, and
+dnl   - one of ncurses-style getmouse or request_mouse_pos is found.
+dnl
+dnl Currently, this probes the following functions, in order:
+dnl
+dnl   - mouse_set
+dnl   - mousemask
+dnl   - mouseinterval
+dnl   - getmouse (with ncurses interface)
+dnl   - request_mouse_pos
+dnl
+dnl To save time, not all functions are probed; only the minimum required to
+dnl determine that curses does (or does not) have usable mouse support.  As a
+dnl result, libraries that support multiple interfaces such as pdcurses might
+dnl not have every supported function reflected in the configuration macros.
+AC_DEFUN([DX_CHECK_CURSES_MOUSE_SUPPORT],
+[DX_CHECK_CURSES_FUNC([mouse_set], [BUTTON1_PRESSED])
+AS_IF([test x"$dx_cv_curses_have_mouse_set" != x"yes"],
+  [DX_CHECK_CURSES_FUNC([mousemask], [BUTTON1_PRESSED,0])])
+AS_CASE([$dx_cv_curses_have_mouse_set$dx_cv_curses_have_mousemask],
+[*yes*], [DX_CHECK_CURSES_FUNC([mouseinterval], [0])
+DX_CHECK_CURSES_GETMOUSE_NCURSES
+AS_IF([test x"$dx_cv_curses_have_getmouse_ncurses" != x"yes"],
+  [DX_CHECK_CURSES_FUNC([request_mouse_pos], [],
+    [switch (BUTTON_STATUS(1)) case BUTTON_PRESSED:;])])
+AS_CASE(
+[$dx_cv_curses_have_getmouse_ncurses$dx_cv_curses_have_request_mouse_pos],
+  [*yes*], [AC_DEFINE([HAVE_CURSES_MOUSE_SUPPORT], [1],
+    [Define to 1 if curses has usable mouse support.])])])])
+
+dnl _DX_CURSES_LINKTEST(message, key, body)
+dnl
+dnl Internal macro common to the tests above.  "message" is used to construct
+dnl the configure output and config.h template description; "key" is used to
+dnl construct macro and cache variable names; "body" is the C function body
+dnl to compile.
+AC_DEFUN([_DX_CURSES_LINKTEST],
+[AC_CACHE_CHECK([whether curses $1], [AS_TR_SH([dx_cv_curses_have_$2])],
+[_dx_save_CFLAGS=$CFLAGS _dx_save_LIBS=$LIBS
+CFLAGS="$CFLAGS $CURSES_CFLAGS" LIBS="$CURSES_LIBS"
+AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <curses.h>
+], [$3;])], [AS_TR_SH([dx_cv_curses_have_$2])=yes],
+[AS_TR_SH([dx_cv_curses_have_$2])=no])
+CFLAGS=$_dx_save_CFLAGS LIBS=$_dx_save_LIBS])
+AS_IF([test x"$AS_TR_SH([dx_cv_curses_have_$2])" = x"yes"],
+  [AC_DEFINE(AS_TR_CPP([HAVE_CURSES_$2]), [1],
+    [Define to 1 if your curses library $1])])])