From 44cf194be4a3400900ef6eca7e31f673dd5cce0a Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Thu, 3 Nov 2011 02:20:51 -0700 Subject: [PATCH] m4: Add robust curses detection and support This commit adds the ax_with_curses.m4 macro from the autoconf-archive project. This also adds support for more plain curses, proper color detection and compartmentalizes the curses autoconf stuff. --- Makefile.am | 5 +- configure.ac | 150 ++++++------ m4/ax_with_curses.m4 | 518 +++++++++++++++++++++++++++++++++++++++++ src/charset.c | 12 +- src/colors.h | 7 +- src/hscroll.h | 7 +- src/list_window.h | 7 +- src/ncfix.h | 6 +- src/ncmpc_curses.h | 32 +++ src/ncu.c | 7 +- src/options.c | 2 +- src/screen.h | 7 +- src/screen_browser.h | 7 +- src/screen_interface.h | 7 +- src/screen_list.h | 7 +- src/song_paint.h | 7 +- src/window.h | 7 +- src/wreadln.c | 16 +- src/wreadln.h | 7 +- 19 files changed, 647 insertions(+), 171 deletions(-) create mode 100644 m4/ax_with_curses.m4 create mode 100644 src/ncmpc_curses.h diff --git a/Makefile.am b/Makefile.am index e93c941..d0b55fc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,6 +5,7 @@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = foreign 1.10 dist-bzip2 subdir-objects AM_CPPFLAGS = \ + $(CURSES_LIB) \ $(LIBMPDCLIENT_CFLAGS) \ $(GLIB_CFLAGS) \ $(LIBLIRCCLIENT_CFLAGS) \ @@ -62,11 +63,13 @@ ncmpc_headers = \ src/plugin.h \ src/lyrics.h \ src/str_pool.h \ - src/lirc.h + src/lirc.h \ + src/ncmpc_curses.h bin_PROGRAMS = src/ncmpc src_ncmpc_LDADD = \ + $(CURSES_LIB) \ $(LIBMPDCLIENT_LIBS) \ $(GLIB_LIBS) \ $(LIBLIRCCLIENT_LIBS) diff --git a/configure.ac b/configure.ac index 1935b1b..4e85b10 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,11 @@ AC_CONFIG_MACRO_DIR([m4]) dnl Check for programs AC_PROG_CC_C99 AC_PROG_INSTALL +AX_WITH_CURSES + +AS_IF([ test "x$ax_cv_curses" = xno ], + [AC_MSG_ERROR([No curses support detected.]) + ]) dnl ======================================================= dnl initialize variables @@ -35,12 +40,10 @@ if test "x$enable_mini" = xyes; then auto=no disable_mini=no auto_mini=no - ncurses=ncurses else auto=auto disable_mini=yes auto_mini=auto - ncurses=auto fi AC_CANONICAL_HOST @@ -49,6 +52,7 @@ case "$host_os" in mingw32* | windows*) LIBS="$LIBS -lws2_32" ;; + *) AC_CHECK_FUNC([socket], [], @@ -63,68 +67,6 @@ mingw32* | windows*) ]) esac - -dnl wide character support -AC_ARG_ENABLE([wide], - AS_HELP_STRING([--enable-wide], - [Enable wide character support]),, - [enable_wide=auto]) - - -dnl ncurses -AC_ARG_WITH([ncurses], - AS_HELP_STRING([--with-ncurses], [compile/link with ncurses library] ), - [ncurses=ncurses]) -AC_ARG_WITH(ncursesw, - AS_HELP_STRING([--with-ncursesw], [compile/link with wide-char ncurses library @<:@default@:>@]), - [ncurses=ncursesw]) - -if test "x$enable_wide" = "xno"; then - if test "x$ncurses" = "xauto"; then - dnl select narrow ncurses - ncurses=ncurses - fi - - if test "x$ncurses" = "xncursesw"; then - AC_MSG_WARN([Narrow ncmpc linking against wide libncurses]) - fi -fi - -if test "x$ncurses" = "xauto"; then - AC_CHECK_LIB([ncursesw], - [initscr], - [ncurses=ncursesw], - [ncurses=ncurses]) -fi - -AC_CHECK_LIB([$ncurses], - [initscr], - [LIBS="$LIBS -l$ncurses"], - [AC_MSG_ERROR($ncurses library is required)]) - -if test "x$ncurses" = "xncursesw"; then - AC_CHECK_HEADER([ncursesw/ncurses.h], - AC_DEFINE([HAVE_NCURSESW_NCURSES_H], [1], [ncursesw/ncurses.h]), - ,) -fi - - -dnl wide character support II - -if test "x$enable_wide" = "xauto" ; then - AC_CHECK_LIB([$ncurses], - [wget_wch], - [enable_wide=yes], - [enable_wide=no]) -fi - -AC_MSG_CHECKING([wide character support]) -AC_MSG_RESULT([$enable_wide]) - -if test "x$enable_wide" = "xyes" ; then - AC_DEFINE([ENABLE_WIDE], [1], [Enable wide character support]) -fi - dnl multi-byte character support AC_ARG_ENABLE([multibyte], @@ -135,7 +77,7 @@ AC_ARG_ENABLE([multibyte], if test x$enable_multibyte = xyes; then AC_DEFINE([ENABLE_MULTIBYTE], [1], [Enable multibyte character support]) else - if test x$enable_wide = xyes; then + if test "x$ax_cv_ncursesw" = xyes; then AC_MSG_WARN(wide characters without multibyte characters makes little sense) fi fi @@ -193,15 +135,28 @@ else fi dnl enable colors -AC_MSG_CHECKING([color support]) AC_ARG_ENABLE([colors], AS_HELP_STRING([--enable-colors], - [Enable color support]),, - [enable_colors=$disable_mini]) -AC_MSG_RESULT([$enable_colors]) -if test "x$enable_colors" = "xyes" ; then - AC_DEFINE([ENABLE_COLORS], [1], [Enable color support]) -fi + [Enable color support]), + [enable_colors=$enableval], + [enable_colors=auto]) +AC_MSG_CHECKING([whether to include color support]) +AS_IF([ test "x$enable_colors" = xyes || test "x$enable_colors" = xauto ], + [AS_IF([ test "x$disable_mini" = xyes], + [AS_IF([ test "x$ax_cv_curses_color" = xyes ], + [AC_MSG_RESULT([yes]) + AC_DEFINE([ENABLE_COLORS], [1], [Enable color support])], + [AS_IF([ test "x$enable_colors" = xyes ], + AC_MSG_ERROR(["No color support found in curses library"]) + AC_MSG_RESULT([no]), + AC_MSG_RESULT([no]) + ) + ]) + ], + [AC_MSG_RESULT([no]) + AC_MSG_WARN(["Colors disabled due to mini mode being enabled."])] + )], + [AC_MSG_RESULT([no])]) dnl test for LIRC support @@ -232,18 +187,36 @@ fi AM_CONDITIONAL(ENABLE_HELP_SCREEN, test x$enable_help_screen = xyes) dnl Optional - curses getmouse support -AC_MSG_CHECKING([whether to include mouse support]) + +dnl AC_CHECK_LIB depends on being able to prepend a '-l', remove the '-l' from CURSES_LIB first +AC_CHECK_LIB([$(expr substr $CURSES_LIB 3 99)], + [getmouse], + [ax_cv_curses_mouse=yes], + [ax_cv_curses_mouse=no]) + AC_ARG_ENABLE([mouse], - AS_HELP_STRING([--enable-mouse], - [Enable curses getmouse support @<:@default=yes@:>@]),, - [enable_mouse=$disable_mini]) -AC_MSG_RESULT([$enable_mouse]) -if test "x$enable_mouse" = "xyes" ; then - AC_CHECK_LIB([$ncurses], - [getmouse], - [AC_DEFINE([HAVE_GETMOUSE], [1], [$ncurses - getmouse()])], - []) -fi + AS_HELP_STRING([--enable-mouse], + [Enable curses getmouse support @<:@default=yes@:>@]), + [enable_mouse=$enableval], + [enable_mouse=auto]) + +AC_MSG_CHECKING([whether to include mouse support]) + +AS_IF([ test "x$enable_mouse" = xyes || test "x$enable_mouse" = xauto ], + [AS_IF([ test "x$disable_mini" = xyes], + [AS_IF([ test "x$ax_cv_curses_mouse" = xyes ], + [AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_GETMOUSE], [1], [Enable mouse support])], + [AC_MSG_RESULT([no]) + AS_IF([ test "x$enable_mouse" = xyes ], + [AC_MSG_ERROR(["No mouse support found in curses library"]) + ]) + ]) + ], + [AC_MSG_RESULT([no]) + AC_MSG_WARN("Mouse disabled due to mini mode being enabled.")] + )], + [AC_MSG_RESULT([no])]) dnl Optional screen - artist AC_MSG_CHECKING([whether to include the artist screen]) @@ -301,8 +274,17 @@ dnl Optional screen - lyrics AC_MSG_CHECKING([whether to include the lyrics screen]) AC_ARG_ENABLE([lyrics-screen], AS_HELP_STRING([--enable-lyrics-screen], - [Enable lyrics screen @<:@default=no@:>@]),, + [Enable lyrics screen @<:@default=no@:>@]), + [enable_lyrics_screen=$enableval], [enable_lyrics_screen=no]) + +case "$host_os" in +mingw32* | windows*) + AS_IF([ test "x$enable_lyrics_screen" = xyes ], + [AC_MSG_ERROR([Lyrics screen is not yet compatible with windows.]) + ]) +esac + if test "x$enable_lyrics_screen" = "xyes" ; then AC_DEFINE(ENABLE_LYRICS_SCREEN, 1, [Enable lyrics screen]) fi diff --git a/m4/ax_with_curses.m4 b/m4/ax_with_curses.m4 new file mode 100644 index 0000000..e5ff6a5 --- /dev/null +++ b/m4/ax_with_curses.m4 @@ -0,0 +1,518 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_with_curses.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_WITH_CURSES +# +# DESCRIPTION +# +# This macro checks whether a SysV or X/Open-compatible Curses library is +# present, along with the associated header file. The NcursesW +# (wide-character) library is searched for first, followed by Ncurses, +# then the system-default plain Curses. The first library found is the +# one returned. +# +# The following options are understood: --with-ncursesw, --with-ncurses, +# --without-ncursesw, --without-ncurses. The "--with" options force the +# macro to use that particular library, terminating with an error if not +# found. The "--without" options simply skip the check for that library. +# The effect on the search pattern is: +# +# (no options) - NcursesW, Ncurses, Curses +# --with-ncurses --with-ncursesw - NcursesW only [*] +# --without-ncurses --with-ncursesw - NcursesW only [*] +# --with-ncursesw - NcursesW only [*] +# --with-ncurses --without-ncursesw - Ncurses only [*] +# --with-ncurses - NcursesW, Ncurses [**] +# --without-ncurses --without-ncursesw - Curses only +# --without-ncursesw - Ncurses, Curses +# --without-ncurses - NcursesW, Curses +# +# [*] If the library is not found, abort the configure script. +# +# [**] If the second library (Ncurses) is not found, abort configure. +# +# The following preprocessor symbols may be defined by this macro if the +# appropriate conditions are met: +# +# HAVE_CURSES - if any SysV or X/Open Curses library found +# HAVE_CURSES_ENHANCED - if library supports X/Open Enhanced functions +# HAVE_CURSES_COLOR - if library supports color (enhanced functions) +# HAVE_CURSES_OBSOLETE - if library supports certain obsolete features +# HAVE_NCURSESW - if NcursesW (wide char) library is to be used +# HAVE_NCURSES - if the Ncurses library is to be used +# +# HAVE_CURSES_H - if is present and should be used +# HAVE_NCURSESW_H - if should be used +# HAVE_NCURSES_H - if should be used +# HAVE_NCURSESW_CURSES_H - if should be used +# HAVE_NCURSES_CURSES_H - if should be used +# +# (These preprocessor symbols are discussed later in this document.) +# +# The following output variable is defined by this macro; it is precious +# and may be overridden on the ./configure command line: +# +# CURSES_LIB - library to add to xxx_LDADD +# +# The library listed in CURSES_LIB is NOT added to LIBS by default. You +# need to add CURSES_LIB to the appropriate xxx_LDADD line in your +# Makefile.am. For example: +# +# prog_LDADD = @CURSES_LIB@ +# +# If CURSES_LIB is set on the configure command line (such as by running +# "./configure CURSES_LIB=-lmycurses"), then the only header searched for +# is . The user may use the CPPFLAGS precious variable to +# override the standard #include search path. If the user needs to +# specify an alternative path for a library (such as for a non-standard +# NcurseW), the user should use the LDFLAGS variable. +# +# The following shell variables may be defined by this macro: +# +# ax_cv_curses - set to "yes" if any Curses library found +# ax_cv_curses_enhanced - set to "yes" if Enhanced functions present +# ax_cv_curses_color - set to "yes" if color functions present +# ax_cv_curses_obsolete - set to "yes" if obsolete features present +# +# ax_cv_ncursesw - set to "yes" if NcursesW library found +# ax_cv_ncurses - set to "yes" if Ncurses library found +# ax_cv_plaincurses - set to "yes" if plain Curses library found +# ax_cv_curses_which - set to "ncursesw", "ncurses", "plaincurses" or "no" +# +# These variables can be used in your configure.ac to determine the level +# of support you need from the Curses library. For example, if you must +# have either Ncurses or NcursesW, you could include: +# +# AX_WITH_CURSES +# if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then +# AX_MSG_ERROR([requires either NcursesW or Ncurses library]) +# fi +# +# If any Curses library will do (but one must be present and must support +# color), you could use: +# +# AX_WITH_CURSES +# if test "x$ax_cv_curses" != xyes || test "x$ax_cv_curses_color" != xyes; then +# AC_MSG_ERROR([requires an X/Open-compatible Curses library with color]) +# fi +# +# Certain preprocessor symbols and shell variables defined by this macro +# can be used to determine various features of the Curses library. In +# particular, HAVE_CURSES and ax_cv_curses are defined if the Curses +# library found conforms to the traditional SysV and/or X/Open Base Curses +# definition. Any working Curses library conforms to this level. +# +# HAVE_CURSES_ENHANCED and ax_cv_curses_enhanced are defined if the +# library supports the X/Open Enhanced Curses definition. In particular, +# the wide-character types attr_t, cchar_t and wint_t, the functions +# wattr_set() and wget_wch() and the macros WA_NORMAL and _XOPEN_CURSES +# are checked. The Ncurses library does NOT conform to this definition, +# although NcursesW does. +# +# HAVE_CURSES_COLOR and ax_cv_curses_color are defined if the library +# supports color functions and macros such as COLOR_PAIR, A_COLOR, +# COLOR_WHITE, COLOR_RED and init_pair(). These are NOT part of the +# X/Open Base Curses definition, but are part of the Enhanced set of +# functions. The Ncurses library DOES support these functions, as does +# NcursesW. +# +# HAVE_CURSES_OBSOLETE and ax_cv_curses_obsolete are defined if the +# library supports certain features present in SysV and BSD Curses but not +# defined in the X/Open definition. In particular, the functions +# getattrs(), getcurx() and getmaxx() are checked. +# +# To use the HAVE_xxx_H preprocessor symbols, insert the following into +# your system.h (or equivalent) header file: +# +# #if defined(HAVE_NCURSESW_CURSES_H) +# # include +# #elif defined(HAVE_NCURSESW_H) +# # include +# #elif defined(HAVE_NCURSES_CURSES_H) +# # include +# #elif defined(HAVE_NCURSES_H) +# # include +# #elif defined(HAVE_CURSES_H) +# # include +# #else +# # error "SysV or X/Open-compatible Curses header file required" +# #endif +# +# For previous users of this macro: you should not need to change anything +# in your configure.ac or Makefile.am, as the previous (serial 10) +# semantics are still valid. However, you should update your system.h (or +# equivalent) header file to the fragment shown above. You are encouraged +# also to make use of the extended functionality provided by this version +# of AX_WITH_CURSES, as well as in the additional macros +# AX_WITH_CURSES_PANEL, AX_WITH_CURSES_MENU and AX_WITH_CURSES_FORM. +# +# LICENSE +# +# Copyright (c) 2009 Mark Pulford +# Copyright (c) 2009 Damian Pietras +# Copyright (c) 2011 Reuben Thomas +# Copyright (c) 2011 John Zaitseff +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 11 + +AU_ALIAS([MP_WITH_CURSES], [AX_WITH_CURSES]) +AC_DEFUN([AX_WITH_CURSES], [ + AC_ARG_VAR([CURSES_LIB], [linker library for Curses, e.g. -lcurses]) + AC_ARG_WITH([ncurses], [AS_HELP_STRING([--with-ncurses], + [force the use of Ncurses or NcursesW])], + [], [with_ncurses=check]) + AC_ARG_WITH([ncursesw], [AS_HELP_STRING([--without-ncursesw], + [do not use NcursesW (wide character support)])], + [], [with_ncursesw=check]) + + ax_saved_LIBS=$LIBS + AS_IF([test "x$with_ncurses" = xyes || test "x$with_ncursesw" = xyes], + [ax_with_plaincurses=no], [ax_with_plaincurses=check]) + + ax_cv_curses_which=no + + # Test for NcursesW + + AS_IF([test "x$CURSES_LIB" = x && test "x$with_ncursesw" != xno], [ + LIBS="$ax_saved_LIBS -lncursesw" + + AC_CACHE_CHECK([for NcursesW wide-character library], [ax_cv_ncursesw], [ + AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])], + [ax_cv_ncursesw=yes], [ax_cv_ncursesw=no]) + ]) + AS_IF([test "x$ax_cv_ncursesw" = xno && test "x$with_ncursesw" = xyes], [ + AC_MSG_ERROR([--with-ncursesw specified but could not find NcursesW library]) + ]) + + AS_IF([test "x$ax_cv_ncursesw" = xyes], [ + ax_cv_curses=yes + ax_cv_curses_which=ncursesw + CURSES_LIB="-lncursesw" + AC_DEFINE([HAVE_NCURSESW], [1], [Define to 1 if the NcursesW library is present]) + AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present]) + + AC_CACHE_CHECK([for working ncursesw/curses.h], [ax_cv_header_ncursesw_curses_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + attr_t d = WA_NORMAL; + cchar_t e; + wint_t f; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + wattr_set(stdscr, d, 0, NULL); + wget_wch(stdscr, &f); + ]])], + [ax_cv_header_ncursesw_curses_h=yes], + [ax_cv_header_ncursesw_curses_h=no]) + ]) + AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xyes], [ + ax_cv_curses_enhanced=yes + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSESW_CURSES_H], [1], [Define to 1 if is present]) + ]) + + AC_CACHE_CHECK([for working ncursesw.h], [ax_cv_header_ncursesw_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + attr_t d = WA_NORMAL; + cchar_t e; + wint_t f; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + wattr_set(stdscr, d, 0, NULL); + wget_wch(stdscr, &f); + ]])], + [ax_cv_header_ncursesw_h=yes], + [ax_cv_header_ncursesw_h=no]) + ]) + AS_IF([test "x$ax_cv_header_ncursesw_h" = xyes], [ + ax_cv_curses_enhanced=yes + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSESW_H], [1], [Define to 1 if is present]) + ]) + + AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h_with_ncursesw], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + attr_t d = WA_NORMAL; + cchar_t e; + wint_t f; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + wattr_set(stdscr, d, 0, NULL); + wget_wch(stdscr, &f); + ]])], + [ax_cv_header_ncurses_h_with_ncursesw=yes], + [ax_cv_header_ncurses_h_with_ncursesw=no]) + ]) + AS_IF([test "x$ax_cv_header_ncurses_h_with_ncursesw" = xyes], [ + ax_cv_curses_enhanced=yes + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if is present]) + ]) + + AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xno && test "x$ax_cv_header_ncursesw_h" = xno && test "x$ax_cv_header_ncurses_h_with_ncursesw" = xno], [ + AC_MSG_WARN([could not find a working ncursesw/curses.h, ncursesw.h or ncurses.h]) + ]) + ]) + ]) + + # Test for Ncurses + + AS_IF([test "x$CURSES_LIB" = x && test "x$with_ncurses" != xno && test "x$ax_cv_curses_which" = xno], [ + LIBS="$ax_saved_LIBS -lncurses" + + AC_CACHE_CHECK([for Ncurses library], [ax_cv_ncurses], [ + AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])], + [ax_cv_ncurses=yes], [ax_cv_ncurses=no]) + ]) + AS_IF([test "x$ax_cv_ncurses" = xno && test "x$with_ncurses" = xyes], [ + AC_MSG_ERROR([--with-ncurses specified but could not find Ncurses library]) + ]) + + AS_IF([test "x$ax_cv_ncurses" = xyes], [ + ax_cv_curses=yes + ax_cv_curses_which=ncurses + CURSES_LIB="-lncurses" + AC_DEFINE([HAVE_NCURSES], [1], [Define to 1 if the Ncurses library is present]) + AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present]) + + AC_CACHE_CHECK([for working ncurses/curses.h], [ax_cv_header_ncurses_curses_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + ]])], + [ax_cv_header_ncurses_curses_h=yes], + [ax_cv_header_ncurses_curses_h=no]) + ]) + AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xyes], [ + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSES_CURSES_H], [1], [Define to 1 if is present]) + ]) + + AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + ]])], + [ax_cv_header_ncurses_h=yes], + [ax_cv_header_ncurses_h=no]) + ]) + AS_IF([test "x$ax_cv_header_ncurses_h" = xyes], [ + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if is present]) + ]) + + AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xno && test "x$ax_cv_header_ncurses_h" = xno], [ + AC_MSG_WARN([could not find a working ncurses/curses.h or ncurses.h]) + ]) + ]) + ]) + + # Test for plain Curses (or if CURSES_LIB was set by user) + + AS_IF([test "x$with_plaincurses" != xno && test "x$ax_cv_curses_which" = xno], [ + AS_IF([test "x$CURSES_LIB" != x], [ + LIBS="$ax_saved_LIBS $CURSES_LIB" + ], [ + LIBS="$ax_saved_LIBS -lcurses" + ]) + + AC_CACHE_CHECK([for Curses library], [ax_cv_plaincurses], [ + AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])], + [ax_cv_plaincurses=yes], [ax_cv_plaincurses=no]) + ]) + + AS_IF([test "x$ax_cv_plaincurses" = xyes], [ + ax_cv_curses=yes + ax_cv_curses_which=plaincurses + AS_IF([test "x$CURSES_LIB" = x], [ + CURSES_LIB="-lcurses" + ]) + AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present]) + + # Check for base conformance (and header file) + + AC_CACHE_CHECK([for working curses.h], [ax_cv_header_curses_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + initscr(); + ]])], + [ax_cv_header_curses_h=yes], + [ax_cv_header_curses_h=no]) + ]) + AS_IF([test "x$ax_cv_header_curses_h" = xyes], [ + AC_DEFINE([HAVE_CURSES_H], [1], [Define to 1 if is present]) + + # Check for X/Open Enhanced conformance + + AC_CACHE_CHECK([for X/Open Enhanced Curses conformance], [ax_cv_plaincurses_enhanced], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + @%:@ifndef _XOPEN_CURSES + @%:@error "this Curses library is not enhanced" + "this Curses library is not enhanced" + @%:@endif + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + attr_t d = WA_NORMAL; + cchar_t e; + wint_t f; + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + wattr_set(stdscr, d, 0, NULL); + wget_wch(stdscr, &f); + ]])], + [ax_cv_plaincurses_enhanced=yes], + [ax_cv_plaincurses_enhanced=no]) + ]) + AS_IF([test "x$ax_cv_plaincurses_enhanced" = xyes], [ + ax_cv_curses_enhanced=yes + ax_cv_curses_color=yes + AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + ]) + + # Check for color functions + + AC_CACHE_CHECK([for Curses color functions], [ax_cv_plaincurses_color], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + ]])], + [ax_cv_plaincurses_color=yes], + [ax_cv_plaincurses_color=no]) + ]) + AS_IF([test "x$ax_cv_plaincurses_color" = xyes], [ + ax_cv_curses_color=yes + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + ]) + + # Check for obsolete functions + + AC_CACHE_CHECK([for obsolete Curses functions], [ax_cv_plaincurses_obsolete], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + ]])], + [ax_cv_plaincurses_obsolete=yes], + [ax_cv_plaincurses_obsolete=no]) + ]) + AS_IF([test "x$ax_cv_plaincurses_obsolete" = xyes], [ + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + ]) + ]) + + AS_IF([test "x$ax_cv_header_curses_h" = xno], [ + AC_MSG_WARN([could not find a working curses.h]) + ]) + ]) + ]) + + AS_IF([test "x$ax_cv_curses" != xyes], [ax_cv_curses=no]) + AS_IF([test "x$ax_cv_curses_enhanced" != xyes], [ax_cv_curses_enhanced=no]) + AS_IF([test "x$ax_cv_curses_color" != xyes], [ax_cv_curses_color=no]) + AS_IF([test "x$ax_cv_curses_obsolete" != xyes], [ax_cv_curses_obsolete=no]) + + LIBS=$ax_saved_LIBS +])dnl diff --git a/src/charset.c b/src/charset.c index 7e2e2d1..34381ad 100644 --- a/src/charset.c +++ b/src/charset.c @@ -35,7 +35,7 @@ charset_init(void) } #endif -#ifdef ENABLE_WIDE +#ifdef HAVE_CURSES_ENHANCED static inline unsigned unicode_char_width(gunichar ch) { @@ -49,17 +49,17 @@ unicode_char_width(gunichar ch) return 1; } -#endif /* ENABLE_WIDE */ +#endif /* HAVE_CURSES_ENHANCED */ unsigned utf8_width(const char *str) { assert(str != NULL); -#if defined(ENABLE_MULTIBYTE) && !defined(ENABLE_WIDE) +#if defined(ENABLE_MULTIBYTE) && !defined(HAVE_CURSES_ENHANCED) return g_utf8_strlen(str, -1); #else -#ifdef ENABLE_WIDE +#ifdef HAVE_CURSES_ENHANCED if (g_utf8_validate(str, -1, NULL)) { size_t len = g_utf8_strlen(str, -1); unsigned width = 0; @@ -148,12 +148,12 @@ utf8_cut_width(char *p, unsigned max_width) { assert(p != NULL); -#ifdef ENABLE_WIDE +#ifdef HAVE_CURSES_ENHANCED if (!g_utf8_validate(p, -1, NULL)) return ascii_cut_width(p, max_width); return wide_cut_width(p, max_width); -#elif defined(ENABLE_MULTIBYTE) && !defined(ENABLE_WIDE) +#elif defined(ENABLE_MULTIBYTE) && !defined(HAVE_CURSES_ENHANCED) return narrow_cut_width(p, max_width); #else return ascii_cut_width(p, max_width); diff --git a/src/colors.h b/src/colors.h index f10cb51..cfe345b 100644 --- a/src/colors.h +++ b/src/colors.h @@ -21,12 +21,7 @@ #define COLORS_H #include "config.h" - -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif +#include "ncmpc_curses.h" enum color { COLOR_TITLE = 1, diff --git a/src/hscroll.h b/src/hscroll.h index 3e8fd79..0b44dad 100644 --- a/src/hscroll.h +++ b/src/hscroll.h @@ -21,15 +21,10 @@ #define HSCROLL_H #include "config.h" +#include "ncmpc_curses.h" #include -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif - /** * This class is used to auto-scroll text which does not fit on the * screen. Call hscroll_init() to initialize the object, diff --git a/src/list_window.h b/src/list_window.h index 8f67c85..bac5d5e 100644 --- a/src/list_window.h +++ b/src/list_window.h @@ -23,16 +23,11 @@ #include "config.h" #include "command.h" #include "colors.h" +#include "ncmpc_curses.h" #include #include -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif - typedef const char * (*list_window_callback_fn_t)(unsigned i, void *data); diff --git a/src/ncfix.h b/src/ncfix.h index e63efa6..fd86452 100644 --- a/src/ncfix.h +++ b/src/ncfix.h @@ -24,11 +24,7 @@ #ifndef NCFIX_H #define NCFIX_H -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif +#include "ncmpc_curses.h" /** * Workaround for "comparison will always evaluate as 'true' for the diff --git a/src/ncmpc_curses.h b/src/ncmpc_curses.h new file mode 100644 index 0000000..99cd7cf --- /dev/null +++ b/src/ncmpc_curses.h @@ -0,0 +1,32 @@ +/* ncmpc (Ncurses MPD Client) + * (c) 2004-2010 The Music Player Daemon Project + * Project homepage: http://musicpd.org + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#if defined(HAVE_NCURSESW_CURSES_H) +# include +#elif defined(HAVE_NCURSESW_H) +# include +#elif defined(HAVE_NCURSES_CURSES_H) +# include +#elif defined(HAVE_NCURSES_H) +# include +#elif defined(HAVE_CURSES_H) +# include +#else +# error "SysV or X/Open-compatible Curses header file required" +#endif diff --git a/src/ncu.c b/src/ncu.c index 65b1c78..40e22ea 100644 --- a/src/ncu.c +++ b/src/ncu.c @@ -19,6 +19,7 @@ #include "ncu.h" #include "config.h" +#include "ncmpc_curses.h" #ifdef ENABLE_COLORS #include "colors.h" @@ -28,12 +29,6 @@ #include "options.h" #endif -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif - static SCREEN *ncu_screen; void diff --git a/src/options.c b/src/options.c index e2051c5..63f8aab 100644 --- a/src/options.c +++ b/src/options.c @@ -172,7 +172,7 @@ handle_option(int c, const char *arg) #ifdef ENABLE_MULTIBYTE " multibyte" #endif -#ifdef ENABLE_WIDE +#ifdef HAVE_CURSES_ENHANCED " wide" #endif #ifdef ENABLE_LOCALE diff --git a/src/screen.h b/src/screen.h index e3b0062..d0ae704 100644 --- a/src/screen.h +++ b/src/screen.h @@ -26,17 +26,12 @@ #include "title_bar.h" #include "progress_bar.h" #include "status_bar.h" +#include "ncmpc_curses.h" #include #include -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif - struct mpdclient; struct screen_functions; diff --git a/src/screen_browser.h b/src/screen_browser.h index 6ba0921..f6cfd5a 100644 --- a/src/screen_browser.h +++ b/src/screen_browser.h @@ -22,15 +22,10 @@ #include "command.h" #include "config.h" +#include "ncmpc_curses.h" #include -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif - struct mpdclient; struct mpdclient_playlist; struct filelist; diff --git a/src/screen_interface.h b/src/screen_interface.h index a853185..bcf442a 100644 --- a/src/screen_interface.h +++ b/src/screen_interface.h @@ -22,16 +22,11 @@ #include "config.h" #include "command.h" +#include "ncmpc_curses.h" #include #include -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif - struct mpdclient; struct screen_functions { diff --git a/src/screen_list.h b/src/screen_list.h index df61f08..aa10e32 100644 --- a/src/screen_list.h +++ b/src/screen_list.h @@ -21,12 +21,7 @@ #define SCREEN_LIST_H #include "config.h" - -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif +#include "ncmpc_curses.h" struct screen_functions; diff --git a/src/song_paint.h b/src/song_paint.h index 10efde4..7a67660 100644 --- a/src/song_paint.h +++ b/src/song_paint.h @@ -21,15 +21,10 @@ #define NCMPC_SONG_PAINT_H #include "config.h" +#include "ncmpc_curses.h" #include -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif - struct mpd_song; struct hscroll; diff --git a/src/window.h b/src/window.h index 5a33012..63e5eb9 100644 --- a/src/window.h +++ b/src/window.h @@ -21,12 +21,7 @@ #define NCMPC_WINDOW_H #include "config.h" - -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif +#include "ncmpc_curses.h" struct window { WINDOW *w; diff --git a/src/wreadln.c b/src/wreadln.c index 44d0002..be4f266 100644 --- a/src/wreadln.c +++ b/src/wreadln.c @@ -27,7 +27,7 @@ #include #include -#if (defined(ENABLE_WIDE) || defined(ENABLE_MULTIBYTE)) && !defined(WIN32) +#if (defined(HAVE_CURSES_ENHANCED) || defined(ENABLE_MULTIBYTE)) && !defined(WIN32) #include #endif @@ -84,7 +84,7 @@ wrln_gcmp_post_cb_t wrln_post_completion_callback = NULL; static unsigned byte_to_screen(const gchar *data, size_t x) { -#if defined(ENABLE_WIDE) || defined(ENABLE_MULTIBYTE) +#if defined(HAVE_CURSES_ENHANCED) || defined(ENABLE_MULTIBYTE) gchar *dup; char *p; unsigned width; @@ -110,7 +110,7 @@ byte_to_screen(const gchar *data, size_t x) static size_t screen_to_bytes(const gchar *data, unsigned width) { -#if defined(ENABLE_WIDE) || defined(ENABLE_MULTIBYTE) +#if defined(HAVE_CURSES_ENHANCED) || defined(ENABLE_MULTIBYTE) size_t length = strlen(data); gchar *dup = g_strdup(data); char *p; @@ -150,7 +150,7 @@ cursor_column(const struct wreadln *wr) static inline size_t right_align_bytes(const gchar *data, size_t right, unsigned width) { -#if defined(ENABLE_WIDE) || defined(ENABLE_MULTIBYTE) +#if defined(HAVE_CURSES_ENHANCED) || defined(ENABLE_MULTIBYTE) gchar *dup; size_t start = 0; @@ -192,7 +192,7 @@ right_align_bytes(const gchar *data, size_t right, unsigned width) static inline size_t next_char_size(const gchar *data) { -#if defined(ENABLE_WIDE) || defined(ENABLE_MULTIBYTE) +#if defined(HAVE_CURSES_ENHANCED) || defined(ENABLE_MULTIBYTE) char *p = locale_to_utf8(data), *q; gunichar c; size_t size; @@ -217,7 +217,7 @@ next_char_size(const gchar *data) static inline size_t prev_char_size(const gchar *data, size_t x) { -#if defined(ENABLE_WIDE) || defined(ENABLE_MULTIBYTE) +#if defined(HAVE_CURSES_ENHANCED) || defined(ENABLE_MULTIBYTE) char *p = locale_to_utf8(data), *q; gunichar c; size_t size; @@ -301,7 +301,7 @@ static inline void drawline(const struct wreadln *wr) doupdate(); } -#if defined(ENABLE_WIDE) || defined(ENABLE_MULTIBYTE) +#if defined(HAVE_CURSES_ENHANCED) || defined(ENABLE_MULTIBYTE) static bool multibyte_is_complete(const char *p, size_t length) { @@ -322,7 +322,7 @@ static void wreadln_insert_byte(struct wreadln *wr, gint key) { size_t rest = strlen(wr->line + wr->cursor) + 1; -#if (defined(ENABLE_WIDE) || defined(ENABLE_MULTIBYTE)) && !defined (WIN32) +#if (defined(HAVE_CURSES_ENHANCED) || defined(ENABLE_MULTIBYTE)) && !defined (WIN32) char buffer[32] = { key }; size_t length = 1; struct pollfd pfd = { diff --git a/src/wreadln.h b/src/wreadln.h index f03a32d..0a4572d 100644 --- a/src/wreadln.h +++ b/src/wreadln.h @@ -21,15 +21,10 @@ #define WREADLN_H #include "config.h" +#include "ncmpc_curses.h" #include -#ifdef HAVE_NCURSESW_NCURSES_H -#include -#else -#include -#endif - #ifndef NCMPC_MINI /* completion callback data */ -- 2.30.2