diff --git a/configure.ac b/configure.ac index c37ff72c..ccfa823c 100644 --- a/configure.ac +++ b/configure.ac @@ -25,14 +25,19 @@ TORRENT_ENABLE_ARCH TORRENT_WITH_SYSROOT TORRENT_WITHOUT_VARIABLE_FDSET() -TORRENT_WITHOUT_NCURSESW() TORRENT_WITHOUT_STATVFS() TORRENT_WITHOUT_STATFS() -ACX_PTHREAD() -CFLAGS="$CFLAGS $PTHREAD_CFLAGS" -CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" -LIBS="$PTHREAD_LIBS $LIBS" +AX_PTHREAD([], AC_MSG_ERROR([requires pthread])) +AX_WITH_CURSES() + +if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then + AC_MSG_ERROR([requires either NcursesW or Ncurses library]) +fi + +CFLAGS="$CFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS" +CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS" +LIBS="$PTHREAD_LIBS $CURSES_LIB $LIBS" PKG_CHECK_MODULES(sigc, sigc++-2.0, CXXFLAGS="$CXXFLAGS $sigc_CFLAGS"; diff --git a/scripts/acx_pthread.m4 b/scripts/acx_pthread.m4 deleted file mode 100644 index ceb161a5..00000000 --- a/scripts/acx_pthread.m4 +++ /dev/null @@ -1,227 +0,0 @@ -dnl PGSGL: When updating, comment out port-specific part below; -dnl see the comment below with the word "PostgreSQL". -dnl -dnl Available from the GNU Autoconf Macro Archive at: -dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html -dnl -AC_DEFUN([ACX_PTHREAD], [ -AC_REQUIRE([AC_CANONICAL_HOST]) -AC_LANG_SAVE -AC_LANG_C -acx_pthread_ok=no - -# We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). -# It gets checked for in the link test anyway. - -# First of all, check if the user has set any of the PTHREAD_LIBS, -# etcetera environment variables, and if threads linking works using -# them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) - AC_MSG_RESULT($acx_pthread_ok) - if test x"$acx_pthread_ok" = xno; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" -fi - -# We must check for the threads library under a number of different -# names; the ordering is very important because some systems -# (e.g. DEC) have both -lpthread and -lpthreads, where one of the -# libraries is broken (non-POSIX). - -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. - -acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config pthreadGC2" - -# The ordering *is* (sometimes) important. Some notes on the -# individual items follow: - -# pthreads: AIX (must check this before -lpthread) -# none: in case threads are in libc; should be tried before -Kthread and -# other compiler flags to prevent continual compiler warnings -# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc -# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# pthread: Linux, etcetera -# --thread-safe: KAI C++ -# pthread-config: use pthread-config program (for GNU Pth library) - -case "${host_cpu}-${host_os}" in - *solaris*) - - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthread or - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: - - acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" - ;; -esac - -if test x"$acx_pthread_ok" = xno; then -for flag in $acx_pthread_flags; do - - tryPTHREAD_CFLAGS="" - tryPTHREAD_LIBS="" - case $flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - tryPTHREAD_CFLAGS="$flag" - ;; - - pthread-config) - # skip this if we already have flags defined, for PostgreSQL - if test x"$PTHREAD_CFLAGS" != x -o x"$PTHREAD_LIBS" != x; then continue; fi - AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) - if test x"$acx_pthread_config" = xno; then continue; fi - tryPTHREAD_CFLAGS="`pthread-config --cflags`" - tryPTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - - *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - tryPTHREAD_LIBS="-l$flag" - ;; - esac - - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="$tryPTHREAD_LIBS $PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS $tryPTHREAD_CFLAGS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - AC_TRY_LINK([#include ], - [pthread_t th; pthread_join(th, 0); - pthread_attr_init(0); pthread_cleanup_push(0, 0); - pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], - [acx_pthread_ok=yes], [acx_pthread_ok=no]) - - if test "x$acx_pthread_ok" = xyes; then - # Don't use options that are ignored by the compiler. - # We find them by checking stderror. - cat >conftest.$ac_ext <<_ACEOF -int -main (int argc, char **argv) -{ - (void) argc; - (void) argv; - return 0; -} -_ACEOF - rm -f conftest.$ac_objext conftest$ac_exeext - if test "`(eval $ac_link 2>&1 1>&5)`" = ""; then - # we continue with more flags because Linux needs -lpthread - # for libpq builds on PostgreSQL. The test above only - # tests for building binaries, not shared libraries. - PTHREAD_LIBS=" $tryPTHREAD_LIBS $PTHREAD_LIBS" - PTHREAD_CFLAGS="$PTHREAD_CFLAGS $tryPTHREAD_CFLAGS" - else acx_pthread_ok=no - fi - fi - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - AC_MSG_RESULT($acx_pthread_ok) -done -fi - -# Various other checks: -if test "x$acx_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Detect AIX lossage: threads are created detached by default - # and the JOINABLE attribute has a nonstandard name (UNDETACHED). - AC_MSG_CHECKING([for joinable pthread attribute]) - AC_TRY_LINK([#include ], - [int attr=PTHREAD_CREATE_JOINABLE;], - ok=PTHREAD_CREATE_JOINABLE, ok=unknown) - if test x"$ok" = xunknown; then - AC_TRY_LINK([#include ], - [int attr=PTHREAD_CREATE_UNDETACHED;], - ok=PTHREAD_CREATE_UNDETACHED, ok=unknown) - fi - if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then - AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok, - [Define to the necessary symbol if this constant - uses a non-standard name on your system.]) - fi - AC_MSG_RESULT(${ok}) - if test x"$ok" = xunknown; then - AC_MSG_WARN([we do not know how to create joinable pthreads]) - fi - - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no -# We always add these in PostgreSQL -# case "${host_cpu}-${host_os}" in -# *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; -# *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; -# esac - AC_MSG_RESULT(${flag}) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - -# Supporting cc_r would require a special CC in all places that -# use libpq, and that is ugly, so we don't do it. Users can still -# define their compiler as cc_r to do thread builds of everything. - # More AIX lossage: must compile with cc_r - AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) -else - PTHREAD_CC="$CC" -fi - -AC_SUBST(PTHREAD_LIBS) -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_CC) - -# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$acx_pthread_ok" = xyes; then - ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) - : -else - acx_pthread_ok=no - $2 -fi -AC_LANG_RESTORE -])dnl ACX_PTHREAD diff --git a/scripts/ax_pthread.m4 b/scripts/ax_pthread.m4 new file mode 100644 index 00000000..e20a388c --- /dev/null +++ b/scripts/ax_pthread.m4 @@ -0,0 +1,309 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# 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 17 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) + AC_MSG_RESULT($ax_pthread_ok) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + *-darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($ax_pthread_ok) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *-osf* | *-hpux*) flag="-D_REENTRANT";; + *solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + flag="-mt -D_REENTRANT" + fi + ;; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + ax_cv_PTHREAD_PRIO_INHERIT, [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/scripts/ax_with_curses.m4 b/scripts/ax_with_curses.m4 new file mode 100644 index 00000000..448dec76 --- /dev/null +++ b/scripts/ax_with_curses.m4 @@ -0,0 +1,546 @@ +# =========================================================================== +# 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) 2012 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 13 + +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]) + ]) + + dnl Test if we need to explicitly link against -ltinfow. + AC_CACHE_CHECK([if curses tinfo library is linked properly], [ax_cv_ncurses_compiled], [ + LIBS="$ax_saved_LIBS $CURSES_LIB" + AC_LINK_IFELSE([AC_LANG_CALL([], [keypad])], [ax_cv_ncurses_compiled=yes], [ax_cv_ncurses_compiled=no]) + + LIBS="$ax_saved_LIBS $CURSES_LIB -ltinfo" + AC_LINK_IFELSE([AC_LANG_CALL([], [keypad])], [ax_cv_tinfo_compiled=yes], [ax_cv_tinfo_compiled=no]) + + LIBS="$ax_saved_LIBS $CURSES_LIB -ltinfow" + AC_LINK_IFELSE([AC_LANG_CALL([], [keypad])], [ax_cv_tinfow_compiled=yes], [ax_cv_tinfow_compiled=no]) + + LIBS=$ax_saved_LIBS + ]) + + AS_IF([test "x$ax_cv_ncurses_compiled" = xno], [ + AS_IF( + [test "x$ax_cv_tinfo_compiled" = xyes], [ + AC_MSG_RESULT([adding libtinfo]) + CURSES_LIB="$CURSES_LIB -ltinfo" + ], + [test "x$ax_cv_tinfow_compiled" = xyes], [ + AC_MSG_RESULT([adding libtinfow]) + CURSES_LIB="$CURSES_LIB -ltinfow" + ], [ + AC_MSG_ERROR([no]) + ]) + ]) + ]) + ]) + + # 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/scripts/checks.m4 b/scripts/checks.m4 index 9bc7a85d..327cd64f 100644 --- a/scripts/checks.m4 +++ b/scripts/checks.m4 @@ -143,6 +143,21 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [ ]) +AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [ + AC_ARG_WITH(kqueue, + [ --without-kqueue Do not check for kqueue support.], + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_KQUEUE + TORRENT_CHECK_KQUEUE_SOCKET_ONLY + fi + ], [ + TORRENT_CHECK_KQUEUE + TORRENT_CHECK_KQUEUE_SOCKET_ONLY + ]) +]) + + AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [ AC_ARG_WITH(variable-fdset, @@ -198,26 +213,6 @@ AC_DEFUN([TORRENT_WITH_POSIX_FALLOCATE], [ ]) ]) -AC_DEFUN([TORRENT_WITHOUT_NCURSESW], [ - AC_ARG_WITH(ncursesw, - [ --without-ncursesw Don't try to use wide char ncurses.], - [ - if test "$withval" = "no"; then - AC_SEARCH_LIBS(add_wch, ncursesw, - AC_DEFINE(HAVE_NCURSESW, 1, defined if ncurses wide character support is available), - AC_SEARCH_LIBS(wbkgdset, ncurses curses,,echo "*** The ncurses library is required!";exit 1) - ) - else - AC_SEARCH_LIBS(wbkgdset, ncurses curses,,echo "*** The ncurses library is required!";exit 1) - fi - ],[ - AC_SEARCH_LIBS(add_wch, ncursesw, - AC_DEFINE(HAVE_NCURSESW, 1, defined if ncurses wide character support is available), - AC_SEARCH_LIBS(wbkgdset, ncurses curses,,echo "*** The ncurses library is required!";exit 1) - ) - ]) -]) - AC_DEFUN([TORRENT_CHECK_STATVFS], [ AC_CHECK_HEADERS(sys/vfs.h sys/statvfs.h sys/statfs.h) diff --git a/scripts/common.m4 b/scripts/common.m4 index ad4edad4..751aa347 100644 --- a/scripts/common.m4 +++ b/scripts/common.m4 @@ -185,7 +185,7 @@ AC_DEFUN([TORRENT_CHECK_POPCOUNT], [ AC_MSG_CHECKING(for __builtin_popcount) AC_COMPILE_IFELSE([AC_LANG_SOURCE([ - void f() { __builtin_popcount(0); } + int f() { return __builtin_popcount(0); } ])], [ AC_MSG_RESULT(yes) diff --git a/src/Makefile.am b/src/Makefile.am index 5be6527a..c28e2550 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,7 +46,8 @@ rtorrent_LDADD = \ display/libsub_display.a \ input/libsub_input.a \ rpc/libsub_rpc.a \ - utils/libsub_utils.a + utils/libsub_utils.a \ + @PTHREAD_LIBS@ rtorrent_SOURCES = \ main.cc diff --git a/src/command_local.cc b/src/command_local.cc index 221db04e..cd3225f2 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -331,7 +331,7 @@ initialize_command_local() { CMD2_VAR_C_STRING("system.client_version", PACKAGE_VERSION); CMD2_VAR_C_STRING("system.library_version", torrent::version()); CMD2_VAR_VALUE ("system.file.allocate", 0); - CMD2_VAR_VALUE ("system.file.max_size", (int64_t)64 << 30); + CMD2_VAR_VALUE ("system.file.max_size", (int64_t)128 << 30); CMD2_VAR_VALUE ("system.file.split_size", -1); CMD2_VAR_STRING ("system.file.split_suffix", ".part"); diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 57a2a49f..c71f1ce0 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -20,8 +20,6 @@ libsub_core_a_SOURCES = \ download_store.h \ http_queue.cc \ http_queue.h \ - log.cc \ - log.h \ manager.cc \ manager.h \ poll_manager.cc \ diff --git a/src/core/dht_manager.cc b/src/core/dht_manager.cc index 0472d686..a3ca8930 100644 --- a/src/core/dht_manager.cc +++ b/src/core/dht_manager.cc @@ -248,7 +248,7 @@ DhtManager::log_statistics(bool force) { if (m_dhtPrevCycle == 1) { char buffer[128]; snprintf(buffer, sizeof(buffer), "DHT bootstrap complete, have %d nodes in %d buckets.", stats.num_nodes, stats.num_buckets); - control->core()->get_log_complete().push_front(buffer); + control->core()->push_log_complete(buffer); m_dhtPrevCycle = stats.cycle; return false; }; @@ -271,7 +271,7 @@ DhtManager::log_statistics(bool force) { stats.max_peers, stats.num_trackers); - control->core()->get_log_complete().push_front(buffer); + control->core()->push_log_complete(buffer); m_dhtPrevCycle = stats.cycle; m_dhtPrevQueriesSent = stats.queries_sent; diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 3f63dc4b..facf9326 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -326,10 +326,8 @@ DownloadFactory::receive_success() { } catch (torrent::input_error& e) { std::string msg = "Command on torrent creation failed: " + std::string(e.what()); - if (m_printLog) { - m_manager->get_log_important().push_front(msg); - m_manager->get_log_complete().push_front(msg); - } + if (m_printLog) + m_manager->push_log_std(msg); if (m_manager->download_list()->find(infohash) != m_manager->download_list()->end()) { // Should stop it, mark it bad. Perhaps even delete it? @@ -345,10 +343,8 @@ DownloadFactory::receive_success() { void DownloadFactory::receive_failed(const std::string& msg) { // Add message to log. - if (m_printLog) { - m_manager->get_log_important().push_front(msg + ": \"" + m_uri + "\""); - m_manager->get_log_complete().push_front(msg + ": \"" + m_uri + "\""); - } + if (m_printLog) + m_manager->push_log_std(msg + ": \"" + m_uri + "\""); m_slotFinished(); } diff --git a/src/core/log.cc b/src/core/log.cc deleted file mode 100644 index 432f69cb..00000000 --- a/src/core/log.cc +++ /dev/null @@ -1,65 +0,0 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - -#include "config.h" - -#include -#include - -#include "globals.h" -#include "log.h" - -namespace core { - -void -Log::push_front(const std::string& msg) { - if (!m_enabled) - return; - - Base::push_front(Type(cachedTime, msg)); - - if (size() > 50) - Base::pop_back(); - - m_signalUpdate.emit(); -} - -Log::iterator -Log::find_older(rak::timer t) { - return std::find_if(begin(), end(), rak::on(rak::mem_ref(&Type::first), std::bind2nd(std::less_equal(), t))); -} - -} diff --git a/src/core/log.h b/src/core/log.h deleted file mode 100644 index 372cdaae..00000000 --- a/src/core/log.h +++ /dev/null @@ -1,88 +0,0 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - -#ifndef RTORRENT_CORE_LOG_H -#define RTORRENT_CORE_LOG_H - -#include -#include -#include - -#include - -namespace core { - -class Log : private std::deque > { -public: - typedef std::pair Type; - typedef std::deque Base; - typedef sigc::signal0 Signal; - - using Base::iterator; - using Base::const_iterator; - using Base::reverse_iterator; - using Base::const_reverse_iterator; - - using Base::begin; - using Base::end; - using Base::rbegin; - using Base::rend; - - using Base::empty; - using Base::size; - - Log() : m_enabled(true) {} - - bool is_enabled() const { return m_enabled; } - - void enable() { m_enabled = true; } - void disable() { m_enabled = false; } - - void push_front(const std::string& msg); - - iterator find_older(rak::timer t); - - Signal& signal_update() { return m_signalUpdate; } - -private: - bool m_enabled; - - Signal m_signalUpdate; -}; - -} - -#endif diff --git a/src/core/manager.cc b/src/core/manager.cc index 5ccf572a..1348fbf5 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -103,47 +103,51 @@ Manager::handshake_log(const sockaddr* sa, int msg, int err, const torrent::Hash switch (msg) { case torrent::ConnectionManager::handshake_incoming: - m_logComplete.push_front("Incoming connection from " + peer + download); + push_log_complete("Incoming connection from " + peer + download); break; case torrent::ConnectionManager::handshake_outgoing: - m_logComplete.push_front("Outgoing connection to " + peer + download); + push_log_complete("Outgoing connection to " + peer + download); break; case torrent::ConnectionManager::handshake_outgoing_encrypted: - m_logComplete.push_front("Outgoing encrypted connection to " + peer + download); + push_log_complete("Outgoing encrypted connection to " + peer + download); break; case torrent::ConnectionManager::handshake_outgoing_proxy: - m_logComplete.push_front("Outgoing proxy connection to " + peer + download); + push_log_complete("Outgoing proxy connection to " + peer + download); break; case torrent::ConnectionManager::handshake_success: - m_logComplete.push_front("Successful handshake: " + peer + download); + push_log_complete("Successful handshake: " + peer + download); break; case torrent::ConnectionManager::handshake_dropped: - m_logComplete.push_front("Dropped handshake: " + peer + " - " + torrent::strerror(err) + download); + push_log_complete("Dropped handshake: " + peer + " - " + torrent::strerror(err) + download); break; case torrent::ConnectionManager::handshake_failed: - m_logComplete.push_front("Handshake failed: " + peer + " - " + torrent::strerror(err) + download); + push_log_complete("Handshake failed: " + peer + " - " + torrent::strerror(err) + download); break; case torrent::ConnectionManager::handshake_retry_plaintext: - m_logComplete.push_front("Trying again without encryption: " + peer + download); + push_log_complete("Trying again without encryption: " + peer + download); break; case torrent::ConnectionManager::handshake_retry_encrypted: - m_logComplete.push_front("Trying again encrypted: " + peer + download); + push_log_complete("Trying again encrypted: " + peer + download); break; default: - m_logComplete.push_front("Unknown handshake message for " + peer + download); + push_log_complete("Unknown handshake message for " + peer + download); break; } } void Manager::push_log(const char* msg) { - m_logImportant.push_front(msg); - m_logComplete.push_front(msg); + if (!pthread_equal(pthread_self(), torrent::main_thread()->pthread())) + throw torrent::internal_error("Manager::push_log(...): Cannot call this function from other threads than 'main'."); + + m_log_important->lock_and_push_log(msg, strlen(msg), 0); + m_log_complete->lock_and_push_log(msg, strlen(msg), 0); } Manager::Manager() : - m_hashingView(NULL) -// m_pollManager(NULL) { + m_hashingView(NULL), + m_log_important(torrent::log_open_log_buffer("important")), + m_log_complete(torrent::log_open_log_buffer("complete")) { m_downloadStore = new DownloadStore(); m_downloadList = new DownloadList(); @@ -160,6 +164,8 @@ Manager::~Manager() { torrent::Throttle::destroy_throttle(m_throttles["NULL"].first); delete m_downloadList; + // TODO: Clean up logs objects. + delete m_downloadStore; delete m_httpQueue; delete m_fileStatusCache; @@ -369,8 +375,7 @@ Manager::set_proxy_address(const std::string& addr) { void Manager::receive_http_failed(std::string msg) { - m_logImportant.push_front("Http download error: \"" + msg + "\""); - m_logComplete.push_front("Http download error: \"" + msg + "\""); + push_log_std("Http download error: \"" + msg + "\""); } void diff --git a/src/core/manager.h b/src/core/manager.h index 610e8f99..cfdae66e 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -40,12 +40,12 @@ #include #include +#include #include #include "download_list.h" #include "poll_manager.h" #include "range_map.h" -#include "log.h" namespace torrent { class Bencode; @@ -85,8 +85,8 @@ public: View* hashing_view() { return m_hashingView; } void set_hashing_view(View* v); - Log& get_log_important() { return m_logImportant; } - Log& get_log_complete() { return m_logComplete; } + torrent::log_buffer* log_important() { return m_log_important; } + torrent::log_buffer* log_complete() { return m_log_complete; } ThrottleMap& throttles() { return m_throttles; } torrent::ThrottlePair get_throttle(const std::string& name); @@ -113,8 +113,8 @@ public: void shutdown(bool force); void push_log(const char* msg); - void push_log_std(const std::string& msg) { m_logImportant.push_front(msg); m_logComplete.push_front(msg); } - void push_log_complete(const std::string& msg) { m_logComplete.push_front(msg); } + void push_log_std(const std::string& msg) { m_log_important->lock_and_push_log(msg.c_str(), msg.size(), 0); m_log_complete->lock_and_push_log(msg.c_str(), msg.size(), 0); } + void push_log_complete(const std::string& msg) { m_log_complete->lock_and_push_log(msg.c_str(), msg.size(), 0); } void handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash); @@ -152,8 +152,8 @@ private: ThrottleMap m_throttles; AddressThrottleMap m_addressThrottles; - Log m_logImportant; - Log m_logComplete; + torrent::log_buffer* m_log_important; + torrent::log_buffer* m_log_complete; }; // Meh, cleanup. diff --git a/src/core/poll_manager.cc b/src/core/poll_manager.cc index 1023b0f1..1a3a0a51 100644 --- a/src/core/poll_manager.cc +++ b/src/core/poll_manager.cc @@ -52,8 +52,6 @@ namespace core { torrent::Poll* create_poll() { - Log* log = &control->core()->get_log_important(); - const char* poll_name = getenv("RTORRENT_POLL"); int maxOpen = sysconf(_SC_OPEN_MAX); @@ -69,20 +67,20 @@ create_poll() { poll = torrent::PollSelect::create(maxOpen); if (poll == NULL) - log->push_front(std::string("Cannot enable '") + poll_name + "' based polling."); + control->core()->push_log_std(std::string("Cannot enable '") + poll_name + "' based polling."); } if (poll != NULL) - log->push_front(std::string("Using '") + poll_name + "' based polling."); + control->core()->push_log_std(std::string("Using '") + poll_name + "' based polling."); else if ((poll = torrent::PollEPoll::create(maxOpen)) != NULL) - log->push_front("Using 'epoll' based polling."); + control->core()->push_log_std("Using 'epoll' based polling."); else if ((poll = torrent::PollKQueue::create(maxOpen)) != NULL) - log->push_front("Using 'kqueue' based polling."); + control->core()->push_log_std("Using 'kqueue' based polling."); else if ((poll = torrent::PollSelect::create(maxOpen)) != NULL) - log->push_front("Using 'select' based polling."); + control->core()->push_log_std("Using 'select' based polling."); else throw torrent::internal_error("Could not create any Poll object."); diff --git a/src/display/attributes.h b/src/display/attributes.h index 54dc2e58..85ca7f87 100644 --- a/src/display/attributes.h +++ b/src/display/attributes.h @@ -39,7 +39,20 @@ #include #include + +#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 // Let us hail the creators of curses for being idiots. The only // clever move they made was in the naming. diff --git a/src/display/window_log.cc b/src/display/window_log.cc index 3b36dbe3..11540224 100644 --- a/src/display/window_log.cc +++ b/src/display/window_log.cc @@ -37,6 +37,8 @@ #include "config.h" #include +#include +#include #include "canvas.h" #include "utils.h" @@ -44,24 +46,25 @@ namespace display { -WindowLog::WindowLog(core::Log* l) : +WindowLog::WindowLog(torrent::log_buffer* l) : Window(new Canvas, 0, 0, 0, extent_full, extent_static), m_log(l) { m_taskUpdate.slot() = std::tr1::bind(&WindowLog::receive_update, this); - // We're trying out scheduled tasks instead. - m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLog::receive_update)); + unsigned int signal_index = torrent::main_thread()->signal_bitfield()->add_signal(std::tr1::bind(&WindowLog::receive_update, this)); + + m_log->lock_and_set_update_slot(std::tr1::bind(&torrent::thread_base::send_event_signal, torrent::main_thread(), signal_index, false)); } WindowLog::~WindowLog() { priority_queue_erase(&taskScheduler, &m_taskUpdate); - m_connUpdate.disconnect(); } WindowLog::iterator WindowLog::find_older() { - return m_log->find_older(cachedTime - rak::timer::from_seconds(60)); + return m_log->find_older(cachedTime.seconds() - 60); + // return m_log->begin(); } void @@ -70,11 +73,13 @@ WindowLog::redraw() { int pos = m_canvas->height(); - for (core::Log::iterator itr = m_log->begin(), last = find_older(); itr != last && pos > 0; ++itr, --pos) { - char buffer[16]; - print_hhmmss_local(buffer, buffer + 16, static_cast(itr->first.seconds())); + for (iterator itr = m_log->end(), last = find_older(); itr != last && pos > 0; --pos) { + itr--; - m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->second.c_str()); + char buffer[16]; + print_hhmmss_local(buffer, buffer + 16, static_cast(itr->timestamp)); + + m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->message.c_str()); } } @@ -86,11 +91,12 @@ WindowLog::receive_update() { return; iterator itr = find_older(); - extent_type height = std::min(std::distance(m_log->begin(), itr), (std::iterator_traits::difference_type)10); + extent_type height = std::min(std::distance(itr, (iterator)m_log->end()), (std::iterator_traits::difference_type)10); if (height != m_maxHeight) { m_minHeight = height != 0 ? 1 : 0; m_maxHeight = height; + mark_dirty(); m_slotAdjust(); } else { @@ -100,7 +106,7 @@ WindowLog::receive_update() { priority_queue_erase(&taskScheduler, &m_taskUpdate); if (height != 0) - priority_queue_insert(&taskScheduler, &m_taskUpdate, (cachedTime + rak::timer::from_seconds(30)).round_seconds()); + priority_queue_insert(&taskScheduler, &m_taskUpdate, (cachedTime + rak::timer::from_seconds(5)).round_seconds()); } } diff --git a/src/display/window_log.h b/src/display/window_log.h index 35769800..4b5dba14 100644 --- a/src/display/window_log.h +++ b/src/display/window_log.h @@ -37,9 +37,7 @@ #ifndef RTORRENT_DISPLAY_WINDOW_LOG_H #define RTORRENT_DISPLAY_WINDOW_LOG_H -#include - -#include "core/log.h" +#include #include "window.h" @@ -47,9 +45,9 @@ namespace display { class WindowLog : public Window { public: - typedef core::Log::iterator iterator; + typedef torrent::log_buffer::const_iterator iterator; - WindowLog(core::Log* l); + WindowLog(torrent::log_buffer* l); ~WindowLog(); virtual void redraw(); @@ -59,10 +57,8 @@ public: private: inline iterator find_older(); - core::Log* m_log; - sigc::connection m_connUpdate; - - rak::priority_item m_taskUpdate; + torrent::log_buffer* m_log; + rak::priority_item m_taskUpdate; }; } diff --git a/src/display/window_log_complete.cc b/src/display/window_log_complete.cc index cf142d91..c8f9c979 100644 --- a/src/display/window_log_complete.cc +++ b/src/display/window_log_complete.cc @@ -44,21 +44,17 @@ namespace display { -WindowLogComplete::WindowLogComplete(core::Log* l) : +WindowLogComplete::WindowLogComplete(torrent::log_buffer* l) : Window(new Canvas, 0, 30, 1, extent_full, extent_full), m_log(l) { - - // We're trying out scheduled tasks instead. - m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLogComplete::receive_update)); } WindowLogComplete::~WindowLogComplete() { - m_connUpdate.disconnect(); } WindowLogComplete::iterator WindowLogComplete::find_older() { - return m_log->find_older(cachedTime - rak::timer::from_seconds(60)); + return m_log->find_older(cachedTime.seconds() - 60); } void @@ -70,28 +66,25 @@ WindowLogComplete::redraw() { int pos = m_canvas->height(); - for (core::Log::iterator itr = m_log->begin(), last = m_log->end(); itr != last && pos > 0; ++itr) { + for (iterator itr = m_log->end(), last = m_log->begin(); itr != last && pos > 0; ) { + itr--; + char buffer[16]; // Use an arbitrary min width of 60 for allowing multiple // lines. This should ensure we don't mess up the display when the // screen is shrunk too much. - unsigned int timeWidth = 3 + print_hhmmss_local(buffer, buffer + 16, static_cast(itr->first.seconds())) - buffer; + unsigned int timeWidth = 3 + print_hhmmss_local(buffer, buffer + 16, static_cast(itr->timestamp)) - buffer; unsigned int logWidth = m_canvas->width() > 60 ? (m_canvas->width() - timeWidth) : (60 - timeWidth); - unsigned int logHeight = (itr->second.size() + logWidth - 1) / logWidth; + unsigned int logHeight = (itr->message.size() + logWidth - 1) / logWidth; for (unsigned int j = logHeight; j > 0 && pos > 0; --j, --pos) if (j == 1) - m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->second.substr(0, m_canvas->width() - timeWidth).c_str()); + m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->message.substr(0, m_canvas->width() - timeWidth).c_str()); else - m_canvas->print(timeWidth, pos - 1, "%s", itr->second.substr(logWidth * (j - 1), m_canvas->width() - timeWidth).c_str()); + m_canvas->print(timeWidth, pos - 1, "%s", itr->message.substr(logWidth * (j - 1), m_canvas->width() - timeWidth).c_str()); } } -void -WindowLogComplete::receive_update() { - mark_dirty(); -} - } diff --git a/src/display/window_log_complete.h b/src/display/window_log_complete.h index 7b40a85f..b4c07b1d 100644 --- a/src/display/window_log_complete.h +++ b/src/display/window_log_complete.h @@ -37,9 +37,7 @@ #ifndef RTORRENT_DISPLAY_WINDOW_LOG_COMPLETE_H #define RTORRENT_DISPLAY_WINDOW_LOG_COMPLETE_H -#include - -#include "core/log.h" +#include #include "window.h" @@ -47,20 +45,17 @@ namespace display { class WindowLogComplete : public Window { public: - typedef core::Log::iterator iterator; + typedef torrent::log_buffer::const_iterator iterator; - WindowLogComplete(core::Log* l); + WindowLogComplete(torrent::log_buffer* l); ~WindowLogComplete(); virtual void redraw(); - void receive_update(); - private: inline iterator find_older(); - core::Log* m_log; - sigc::connection m_connUpdate; + torrent::log_buffer* m_log; }; } diff --git a/src/input/bindings.h b/src/input/bindings.h index e3f3a7a2..6e3b0a9c 100644 --- a/src/input/bindings.h +++ b/src/input/bindings.h @@ -38,9 +38,10 @@ #define RTORRENT_INPUT_BINDINGS_H #include -#include #include +#include "display/attributes.h" + namespace input { class Bindings : private std::map > { diff --git a/src/input/text_input.cc b/src/input/text_input.cc index 32c61bf8..abb6aa7f 100644 --- a/src/input/text_input.cc +++ b/src/input/text_input.cc @@ -36,7 +36,7 @@ #include "config.h" -#include +#include "display/attributes.h" #include "text_input.h" diff --git a/src/main.cc b/src/main.cc index 773a6264..2d50006c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -183,6 +183,9 @@ main(int argc, char** argv) { cachedTime = rak::timer::current(); + // Initialize logging: + torrent::log_initialize(); + control = new Control; worker_thread = new ThreadWorker(); @@ -205,6 +208,9 @@ main(int argc, char** argv) { // to process new non-socket events. SignalHandler::set_handler(SIGUSR1, sigc::ptr_fun(&do_nothing)); + torrent::log_add_group_output(torrent::LOG_NOTICE, "important"); + torrent::log_add_group_output(torrent::LOG_INFO, "complete"); + torrent::Poll::slot_create_poll() = std::tr1::bind(&core::create_poll); torrent::initialize(); @@ -215,13 +221,6 @@ main(int argc, char** argv) { // torrent::ConnectionManager* are valid etc. initialize_commands(); - // Initialize logging: - torrent::log_initialize(); - torrent::log_open_output("console", std::bind(&core::Manager::push_log, control->core(), std::placeholders::_1)); - torrent::log_add_group_output(torrent::LOG_INFO, "console"); - - lt_log_print(torrent::LOG_INFO, "Started logging to 'console'."); - if (OptionParser::has_flag('D', argc, argv)) { rpc::call_command_set_value("method.use_deprecated.set", false); lt_log_print(torrent::LOG_WARN, "Disabled deprecated commands."); diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc index 224d4d11..edacc9b1 100644 --- a/src/ui/download_list.cc +++ b/src/ui/download_list.cc @@ -74,10 +74,10 @@ DownloadList::DownloadList() : m_uiArray[DISPLAY_DOWNLOAD] = NULL; m_uiArray[DISPLAY_DOWNLOAD_LIST] = new ElementDownloadList(); - m_uiArray[DISPLAY_LOG] = new ElementLogComplete(&control->core()->get_log_complete()); + m_uiArray[DISPLAY_LOG] = new ElementLogComplete(control->core()->log_complete()); m_uiArray[DISPLAY_STRING_LIST] = new ElementStringList(); - m_windowLog = new WLog(&control->core()->get_log_important()); + m_windowLog = new WLog(control->core()->log_important()); setup_keys(); } diff --git a/src/ui/element_log_complete.cc b/src/ui/element_log_complete.cc index 194645ce..45602a5c 100644 --- a/src/ui/element_log_complete.cc +++ b/src/ui/element_log_complete.cc @@ -37,6 +37,8 @@ #include "config.h" #include +#include +#include #include "display/frame.h" #include "display/manager.h" @@ -48,9 +50,13 @@ namespace ui { -ElementLogComplete::ElementLogComplete(core::Log* l) : +ElementLogComplete::ElementLogComplete(torrent::log_buffer* l) : m_window(NULL), m_log(l) { + + unsigned int signal_index = torrent::main_thread()->signal_bitfield()->add_signal(std::tr1::bind(&ElementLogComplete::received_update, this)); + + m_log->lock_and_set_update_slot(std::tr1::bind(&torrent::thread_base::send_event_signal, torrent::main_thread(), signal_index, false)); } void @@ -86,4 +92,10 @@ ElementLogComplete::window() { return m_window; } +void +ElementLogComplete::received_update() { + if (m_window != NULL) + m_window->mark_dirty(); +} + } diff --git a/src/ui/element_log_complete.h b/src/ui/element_log_complete.h index c02e2c4c..e867206d 100644 --- a/src/ui/element_log_complete.h +++ b/src/ui/element_log_complete.h @@ -37,7 +37,7 @@ #ifndef RTORRENT_UI_ELEMENT_LOG_COMPLETE_H #define RTORRENT_UI_ELEMENT_LOG_COMPLETE_H -#include "core/log.h" +#include #include "element_base.h" @@ -53,7 +53,7 @@ class ElementLogComplete : public ElementBase { public: typedef display::WindowLogComplete WLogComplete; - ElementLogComplete(core::Log* l); + ElementLogComplete(torrent::log_buffer* l); void activate(display::Frame* frame, bool focus = true); void disable(); @@ -61,9 +61,11 @@ public: display::Window* window(); private: + void received_update(); + WLogComplete* m_window; - core::Log* m_log; + torrent::log_buffer* m_log; }; }