diff --git a/configure.ac b/configure.ac index 988fc35e537e21c1680ba68c5e02b282227e57d0..e0108a27a838387af7d1b79794aa8896bd535517 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl SFLPhone - configure.ac for automake 1.9 and autoconf 2.59 dnl dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([SFLphone],[0.9.3],[sflphoneteam@savoirfairelinux.com],[sflphone]) +AC_INIT([SFLphone],[0.9.4],[sflphoneteam@savoirfairelinux.com],[sflphone]) AC_COPYRIGHT([[Copyright (c) Savoir-Faire Linux 2004-2009]]) AC_REVISION([$Revision$]) @@ -39,7 +39,8 @@ AC_CONFIG_FILES([src/Makefile \ src/dbus/Makefile \ src/plug-in/audiorecorder/Makefile \ src/plug-in/Makefile \ - src/plug-in/test/Makefile]) + src/plug-in/test/Makefile \ + src/hooks/Makefile]) dnl Unitary test section AC_CONFIG_FILES([test/Makefile]) @@ -150,6 +151,12 @@ if test "x${have_libpj}" = "xfalse" ; then fi AC_SUBST(SIP_CFLAGS) +dnl Check for uuid development package - name: uuid-dev +UUID_MIN_VERSION=1.0 +PKG_CHECK_MODULES(UUID, uuid >= ${UUID_MIN_VERSION}) +AC_SUBST(UUID_CFLAGS) +AC_SUBST(UUID_LIBS) + dnl Check for alsa development package - name: libasound2-dev LIBASOUND2_MIN_VERSION=1.0 PKG_CHECK_MODULES(ALSA, alsa >= ${LIBASOUND2_MIN_VERSION}) @@ -188,18 +195,11 @@ PKG_CHECK_MODULES(DBUSCPP, dbus-c++-1 >= ${LIBDBUSCPP_MIN_VERSION}) AC_SUBST(DBUSCPP_LIBS) AC_SUBST(DBUSCPP_CFLAGS) -LIBOPENSSL_MIN_VERSION=0.9.8 -PKG_CHECK_MODULES(LIBOPENSSL, libssl >= ${LIBOPENSSL_MIN_VERSION}) -AC_SUBST(LIBOPENSSL_LIBS) -AC_SUBST(LIBOPENSSL_CFLAGS) - dnl Check for libcppunit-dev CPPUNIT_MIN_VERSION=1.12 PKG_CHECK_MODULES(CPPUNIT, cppunit >= ${CPPUNIT_MIN_VERSION}) AC_SUBST(CPPUNIT_LIBS) -LIBSSL_MIN_VERSION=0.9.8 - # check for libgsm1 (doesn't use pkg-config) dnl Check for libgsm AC_ARG_WITH([gsm], @@ -270,14 +270,14 @@ AC_ARG_WITH([iax2], LIBIAX2= AS_IF([test "x$with_iax2" != xno], - [AC_CHECK_LIB([iax2], [iax_init], + [AC_CHECK_HEADER([iax2/iax.h], , AC_MSG_FAILURE([Unable to find the libiax2 headers. You may need to install sflphone-iax2-dev package. You may use --without-iax2 to compile without iax2 protocol support.]))] + [AC_CHECK_LIB([iax2], [iax_init], [], [AC_MSG_FAILURE( - [libiax2 link test failed. You need the sflphone-iax2 package. You may use --without-iax2 to compile without iax2 protocol support.])] + [libiax2 link test failed. You may use --without-iax2 to compile without iax2 protocol support.])] ) - ] - [AC_CHECK_HEADER([iax2/iax.h], , AC_MSG_FAILURE([Unable to find the libiax2 headers. You may need to install sflphone-iax2-dev package. You may use --without-iax2 to compile without iax2 protocol support.]))] - ) + ] +) AC_DEFINE([HAVE_IAX], test "x$with_iax2" = "xyes", [Define if you have libiax2]) AM_CONDITIONAL(USE_IAX, test "x$with_iax2" = "xyes" ) diff --git a/debian/changelog b/debian/changelog index a9a2d466e2f55973d8e2469f393913399fc2a141..82738fe39e45b91e3ac4d680a3d0c2706644fda3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +sflphone (0.9.4-0beta1) %system%; urgency=low + + [ Alexandre Savard ] + * Display codec used during conversation on the GUI + * Enable/disable STUN parameters at runtime + * Refactor search bar use + [ Emmanuel Milou ] + * Build system fixes + * Implement SIP re-invite + * Implement IP to IP call + [ Julien Bonjean ] + * Integrate GNOME address book based on evolution data server + + -- Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> Fri, 20 Mar 2009 18:29:15 -0500 + + sflphone (0.9.3-0ubuntu3) %system%; urgency=low [ Alexandre Savard ] diff --git a/debian/control.intrepid b/debian/control.intrepid index efcff9811b55723f4e4cf5e7ea66d40fd9a1a374..737fc36b64c051d0cbee4f8b4dff548f014d2234 100644 --- a/debian/control.intrepid +++ b/debian/control.intrepid @@ -2,7 +2,7 @@ Source: sflphone Maintainer: SavoirFaireLinux Inc <emmanuel.milou@savoirfairelinux.com> Section: gnome Priority: optional -Build-Depends: debhelper (>= 5), autoconf, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libcppunit-dev, libgsm1-dev, libspeex-dev, libtool, libgtk2.0-dev, libsexy-dev, libdbus-1-dev, libdbus-glib-1-dev, libnotify-dev, libasound2-dev, libspeexdsp-dev +Build-Depends: debhelper (>= 5), autoconf, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libcppunit-dev, libgsm1-dev, libspeex-dev, libtool, libgtk2.0-dev, libsexy-dev, libdbus-1-dev, libdbus-glib-1-dev, libnotify-dev, libasound2-dev, libspeexdsp-dev, uuid-dev Standards-Version: 3.8.0 Package: sflphone diff --git a/debian/control.jaunty b/debian/control.jaunty index e1d859266bfa82acbb19c706427ce25bd8f3680f..b88584932302734a1bd1de6494b94d9040584f73 100644 --- a/debian/control.jaunty +++ b/debian/control.jaunty @@ -2,7 +2,7 @@ Source: sflphone Maintainer: SavoirFaireLinux Inc <emmanuel.milou@savoirfairelinux.com> Section: gnome Priority: optional -Build-Depends: debhelper (>= 5), autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libcppunit-dev, libgsm1-dev, libspeex-dev, libtool, libgtk2.0-dev, libsexy-dev, libdbus-1-dev, libdbus-glib-1-dev, libnotify-dev, libasound2-dev, libspeexdsp-dev +Build-Depends: debhelper (>= 5), autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libcppunit-dev, libgsm1-dev, libspeex-dev, libtool, libgtk2.0-dev, libsexy-dev, libdbus-1-dev, libdbus-glib-1-dev, libnotify-dev, libasound2-dev, libspeexdsp-dev, uuid-dev Standards-Version: 3.7.3 Package: sflphone diff --git a/debian/rules b/debian/rules index fd00d4698a8c5990de34d79b2a027973d7334c2f..c67463555b7fb6a22722ba263014dc2e120a600a 100755 --- a/debian/rules +++ b/debian/rules @@ -20,12 +20,12 @@ configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. + cd libs/dbus-c++; ./autogen.sh; ./configure + cd libs/libiax2; ./gen.sh; ./configure + cd libs/pjproject-1.0.1; ./configure ./autogen.sh --prefix=/usr --with-debug cd sflphone-gtk; ./autogen.sh --prefix=/usr - cd libs/pjproject-1.0.1; ./configure touch configure-stamp - cd libs/dbus-c++; ./configure - cd libs/libiax2; ./configure #Architecture diff --git a/libs/dbus-c++/INSTALL b/libs/dbus-c++/INSTALL index 23e5f25d0e5f85798dcfb368ecb2f04f59777f61..d3c5b40a94091285c27361905f591af64c1f7b21 100644 --- a/libs/dbus-c++/INSTALL +++ b/libs/dbus-c++/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free -Software Foundation, Inc. +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. @@ -10,7 +10,10 @@ unlimited permission to copy, distribute and modify it. Basic Installation ================== -These are generic installation instructions. +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -23,9 +26,9 @@ debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is +the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale -cache files.) +cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail @@ -35,20 +38,17 @@ some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. + `./configure' to configure the package for your system. - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. 2. Type `make' to compile the package. @@ -67,6 +67,9 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. + 6. Often, you can also type `make uninstall' to remove the installed + files again. + Compilers and Options ===================== @@ -78,7 +81,7 @@ details on some of the pertinent environment variables. by setting variables in the command line or in the environment. Here is an example: - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. @@ -87,17 +90,15 @@ Compiling For Multiple Architectures You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the +own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. Installation Names ================== @@ -190,12 +191,12 @@ them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). Here is a another example: +overridden in the site shell script). - /bin/bash ./configure CONFIG_SHELL=/bin/bash +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: -Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent -configuration-related scripts to be executed by `/bin/bash'. + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== diff --git a/libs/dbus-c++/depcomp b/libs/dbus-c++/depcomp index 04701da536f33a7c39d7bb01b87a70ae3a776df5..e5f9736c7239301c765e2d7abefb9bb9b9237ac5 100755 --- a/libs/dbus-c++/depcomp +++ b/libs/dbus-c++/depcomp @@ -1,9 +1,10 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2005-07-09.11 +scriptversion=2007-03-29.01 -# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software +# Foundation, Inc. # 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 @@ -91,7 +92,20 @@ gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. - "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" stat=$? if test $stat -eq 0; then : else @@ -201,34 +215,39 @@ aix) # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` - tmpdepfile="$stripped.u" + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u "$@" -M fi stat=$? - if test -f "$tmpdepfile"; then : - else - stripped=`echo "$stripped" | sed 's,^.*/,,'` - tmpdepfile="$stripped.u" - fi - if test $stat -eq 0; then : else - rm -f "$tmpdepfile" + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done if test -f "$tmpdepfile"; then - outname="$stripped.o" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" - sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile @@ -276,6 +295,46 @@ icc) rm -f "$tmpdepfile" ;; +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. @@ -288,13 +347,13 @@ tru64) if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a - # static library. This mecanism is used in libtool 1.4 series to + # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in in $dir.libs/$base.o.d and + # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is diff --git a/libs/dbus-c++/install-sh b/libs/dbus-c++/install-sh index 4d4a9519eaf88b18fb157dfe5fae59c1c5d005c7..a5897de6ea7f74f83fd793474bb4738d32884719 100755 --- a/libs/dbus-c++/install-sh +++ b/libs/dbus-c++/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2005-05-14.22 +scriptversion=2006-12-25.00 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -39,38 +39,68 @@ scriptversion=2005-05-14.22 # when there is no Makefile. # # This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. +# from scratch. + +nl=' +' +IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi -# put in absolute paths if you don't have them in your path; or use env. vars. +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" +posix_mkdir= + +# Desired mode of installed file. +mode=0755 -chmodcmd="$chmodprog 0755" -chowncmd= chgrpcmd= -stripcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog rmcmd="$rmprog -f" -mvcmd="$mvprog" +stripcmd= + src= dst= dir_arg= -dstarg= +dst_arg= + +copy_on_change=false no_target_directory= -usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... @@ -80,81 +110,86 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --c (ignored) --d create directories instead of installing files. --g GROUP $chgrpprog installed files to GROUP. --m MODE $chmodprog installed files to MODE. --o USER $chownprog installed files to USER. --s $stripprog installed files. --t DIRECTORY install into DIRECTORY. --T report an error if DSTFILE is a directory. ---help display this help and exit. ---version display version info and exit. + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG " -while test -n "$1"; do +while test $# -ne 0; do case $1 in - -c) shift - continue;; + -c) ;; + + -C) copy_on_change=true;; - -d) dir_arg=true - shift - continue;; + -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; + shift;; --help) echo "$usage"; exit $?;; - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; -o) chowncmd="$chownprog $2" - shift - shift - continue;; + shift;; - -s) stripcmd=$stripprog - shift - continue;; + -s) stripcmd=$stripprog;; - -t) dstarg=$2 - shift - shift - continue;; + -t) dst_arg=$2 + shift;; - -T) no_target_directory=true - shift - continue;; + -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; - *) # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - test -n "$dir_arg$dstarg" && break - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dstarg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dstarg" - shift # fnord - fi - shift # arg - dstarg=$arg - done + --) shift break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; esac + shift done -if test -z "$1"; then +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 @@ -164,24 +199,47 @@ if test -z "$1"; then exit 0 fi +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + for src do # Protect names starting with `-'. case $src in - -*) src=./$src ;; + -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src - src= - - if test -d "$dst"; then - mkdircmd=: - chmodcmd= - else - mkdircmd=$mkdirprog - fi + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. @@ -190,71 +248,199 @@ do exit 1 fi - if test -z "$dstarg"; then + if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi - dst=$dstarg + dst=$dst_arg # Protect names starting with `-'. case $dst in - -*) dst=./$dst ;; + -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then - echo "$0: $dstarg: Is a directory" >&2 + echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi - dst=$dst/`basename "$src"` + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? fi fi - # This sed command emulates the dirname command. - dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac - # Make sure that the destination directory exists. + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else - # Skip lots of stat calls in the usual case. - if test ! -d "$dstdir"; then - defaultIFS=' - ' - IFS="${IFS-$defaultIFS}" + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. - oIFS=$IFS - # Some sh's can't handle IFS=/ for some reason. - IFS='%' - set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` - shift - IFS=$oIFS + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac - pathcomp= + eval "$initialize_posix_glob" - while test $# -ne 0 ; do - pathcomp=$pathcomp$1 + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir shift - if test ! -d "$pathcomp"; then - $mkdirprog "$pathcomp" - # mkdir can fail with a `File exist' error in case several - # install-sh are creating the directory concurrently. This - # is OK. - test -d "$pathcomp" || exit + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true fi - pathcomp=$pathcomp/ - done + fi fi if test -n "$dir_arg"; then - $doit $mkdircmd "$dst" \ - && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ - && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ - && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ - && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } - + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else - dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ @@ -262,10 +448,9 @@ do # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - trap '(exit $?); exit' 1 2 13 15 # Copy the file name to the temp name. - $doit $cpprog "$src" "$dsttmp" && + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -273,48 +458,59 @@ do # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ - && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ - && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ - && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && - - # Now rename the file to the real destination. - { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ - || { - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - if test -f "$dstdir/$dstfile"; then - $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ - || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ - || { - echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 - (exit 1); exit 1 - } - else - : - fi - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" - } - } - fi || { (exit 1); exit 1; } + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi done -# The final little trick to "correctly" pass the exit status to the exit trap. -{ - (exit 0); exit 0 -} - # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" diff --git a/libs/dbus-c++/missing b/libs/dbus-c++/missing index 894e786e16c1d0d94dfc08d6b475270fe1418d6a..1c8ff7049d8f3aaa9741c53e7f3145d9b76a77d8 100755 --- a/libs/dbus-c++/missing +++ b/libs/dbus-c++/missing @@ -1,9 +1,9 @@ #! /bin/sh # Common stub for a few missing GNU programs while installing. -scriptversion=2005-06-08.21 +scriptversion=2006-05-10.23 -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. @@ -33,6 +33,8 @@ if test $# -eq 0; then fi run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. @@ -44,7 +46,7 @@ fi msg="missing on your system" -case "$1" in +case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= @@ -77,6 +79,7 @@ Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c @@ -106,7 +109,7 @@ esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). -case "$1" in +case $1 in lex|yacc) # Not GNU programs, they don't have --version. ;; @@ -135,7 +138,7 @@ esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. -case "$1" in +case $1 in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if @@ -164,7 +167,7 @@ WARNING: \`$1' is $msg. You should only need it if test -z "$files" && files="config.h" touch_files= for f in $files; do - case "$f" in + case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; @@ -192,8 +195,8 @@ WARNING: \`$1' is needed, but is $msg. You can get \`$1' as part of \`Autoconf' from any GNU archive site." - file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` - test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else @@ -214,25 +217,25 @@ WARNING: \`$1' $msg. You should only need it if in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then + if test $# -ne 1; then eval LASTARG="\${$#}" - case "$LASTARG" in + case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then + if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then + if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi - if [ ! -f y.tab.h ]; then + if test ! -f y.tab.h; then echo >y.tab.h fi - if [ ! -f y.tab.c ]; then + if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; @@ -244,18 +247,18 @@ WARNING: \`$1' is $msg. You should only need it if in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c - if [ $# -ne 1 ]; then + if test $# -ne 1; then eval LASTARG="\${$#}" - case "$LASTARG" in + case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then + if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi - if [ ! -f lex.yy.c ]; then + if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; @@ -267,11 +270,9 @@ WARNING: \`$1' is $msg. You should only need it if \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` - fi - if [ -f "$file" ]; then + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then touch $file else test -z "$file" || exec >$file @@ -289,11 +290,17 @@ WARNING: \`$1' is $msg. You should only need it if DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi @@ -317,13 +324,13 @@ WARNING: \`$1' is $msg. You should only need it if fi firstarg="$1" if shift; then - case "$firstarg" in + case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac - case "$firstarg" in + case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 diff --git a/libs/libiax2/INSTALL b/libs/libiax2/INSTALL index 81fa6ffa451ee21fd1c60d4ba33acd5c36bc6865..5bb6e7b7e1a1d3ba4362b1467fabbf2acb70dcbd 120000 --- a/libs/libiax2/INSTALL +++ b/libs/libiax2/INSTALL @@ -1 +1 @@ -/usr/share/automake-1.9/INSTALL \ No newline at end of file +/usr/share/automake-1.10/INSTALL \ No newline at end of file diff --git a/libs/libiax2/iax2-config.in b/libs/libiax2/iax2-config.in index 360b79f6d7b96c8b485d6a07e13d8e04b962bd4d..295e69a97b706bb34ce8a97b870708222643fc55 100644 --- a/libs/libiax2/iax2-config.in +++ b/libs/libiax2/iax2-config.in @@ -1,11 +1,11 @@ #!/bin/sh -iax_libs="-L/usr/lib -liax2" -iax_cflags="" - prefix=@prefix@ exec_prefix=@exec_prefix@ exec_prefix_set=no +iax_libs="-L$prefix -liax2" +iax_cflags="" + usage="\ Usage: iax2-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags]" diff --git a/po/fr.po b/po/fr.po index 95c7c9f0c8cc68fe42ac5ecc15363a152692c706..0d95e0cefa7ea67399ed6961240c2d8afd0e9365 100644 --- a/po/fr.po +++ b/po/fr.po @@ -45,7 +45,7 @@ msgstr "Réseau non trouvé" #: ../sflphone-gtk/src/accountlist.c:176 msgid "Host unreachable" -msgstr "_Serveur introuvable" +msgstr "Serveur introuvable" #: ../sflphone-gtk/src/accountlist.c:179 msgid "Stun configuration error" diff --git a/sflphone-gtk/configure.ac b/sflphone-gtk/configure.ac index 2864ef4cf513198a24413a24614d56ede7110563..e6e25412930a5348f41dd659386bd3fe14909bb8 100644 --- a/sflphone-gtk/configure.ac +++ b/sflphone-gtk/configure.ac @@ -1,10 +1,10 @@ -AC_INIT([SFLphone],[0.9.3],[sflphoneteam@savoirfairelinux.com],[sflphone]) +AC_INIT([SFLphone],[0.9.4],[sflphoneteam@savoirfairelinux.com],[sflphone]) AM_CONFIG_HEADER(config.h) LT_INIT PACKAGE=SFLphone -VERSION=0.9.3 +VERSION=0.9.4 AM_INIT_AUTOMAKE($PACKAGE,$VERSION) AC_CONFIG_MACRO_DIR([m4]) @@ -26,17 +26,17 @@ fi AC_PROG_CC AC_PROG_INSTALL AC_STDC_HEADERS +AC_PROG_LIBTOOL PKG_CHECK_MODULES(DEPS, \ dbus-glib-1 >= 0.35 \ libnotify >= 0.4 \ gtk+-2.0 >= 2.2 \ glib-2.0 >= 2.2 \ - libsexy >= 0.1 \ + libsexy >= 0.1 \ libebook-1.2 >= 2.22 ) - AC_SUBST(DEPS_CFLAGS) AC_SUBST(DEPS_LIBS) diff --git a/sflphone-gtk/src/Makefile.am b/sflphone-gtk/src/Makefile.am index 0f4ed7d1faa047df6257a0f79af7848732c7008f..5947dcd0830475723a046da865e58f49e7c15ce1 100644 --- a/sflphone-gtk/src/Makefile.am +++ b/sflphone-gtk/src/Makefile.am @@ -39,11 +39,12 @@ sflphone_gtk_SOURCES = \ codeclist.c \ timestamp.c \ reqaccount.c \ - addressbook-config.c + addressbook-config.c \ + hooks-config.c noinst_HEADERS = actions.h dbus.h sflnotify.h mainwindow.h calllist.h dialpad.h audioconf.h codeclist.h assistant.h \ callmanager-glue.h errors.h sflphone_const.h configurationmanager-glue.h instance-glue.h menus.h calltab.h calltree.h configwindow.h \ - accountlist.h accountwindow.h marshaller.h sliders.h $(STATUSICON_HEADER) timestamp.h searchfilter.h reqaccount.h addressbook-config.h + accountlist.h accountwindow.h marshaller.h sliders.h $(STATUSICON_HEADER) timestamp.h searchfilter.h reqaccount.h addressbook-config.h hooks-config.h EXTRA_DIST = marshaller.list diff --git a/sflphone-gtk/src/actions.c b/sflphone-gtk/src/actions.c index dd5658d93554353fc946b7e0120afe22c1bd41ce..4e850958329d331bf6b2c030b496f1a8a426a722 100644 --- a/sflphone-gtk/src/actions.c +++ b/sflphone-gtk/src/actions.c @@ -230,10 +230,11 @@ gboolean sflphone_init() else { dbus_register(getpid(), "Gtk+ Client"); - current_calls = calltab_init(); - history = calltab_init(); - contacts = calltab_init(); - //if(SHOW_SEARCHBAR) histfilter = create_filter(GTK_TREE_MODEL(history->store)); + current_calls = calltab_init(NULL); + // history = calltab_init("history"); + contacts = calltab_init("contacts"); + history = calltab_init("history"); + histfilter = create_filter(GTK_TREE_MODEL(history->store)); init(); account_list_init (); codec_list_init(); @@ -295,6 +296,7 @@ sflphone_hang_up() void sflphone_pick_up() { + call_t * selectedCall = call_get_selected(active_calltree); if(selectedCall) { @@ -373,7 +375,6 @@ sflphone_off_hold () g_print("Currently recording! \n"); else g_print("Not recording currently \n"); - } @@ -529,7 +530,7 @@ process_dialing(call_t * c, guint keyval, gchar * key) call_t * sflphone_new_call() { - + call_t *c; gchar *from, *to; @@ -680,10 +681,11 @@ sflphone_keypad( guint keyval, gchar * key) sflphone_place_call ( call_t * c ) { + if(c->state == CALL_STATE_DIALING && strcmp(c->to, "") != 0) { - - format_phone_number (&c->to); + + //format_phone_number (&c->to); if( account_list_get_size() == 0 ) { @@ -699,19 +701,23 @@ sflphone_place_call ( call_t * c ) else { + + account_t * current; - if(c->accountID != 0) + if(g_strcasecmp(c->accountID, "") != 0) { current = account_list_get_by_id(c->accountID); - else + } else { current = account_list_get_current(); - + } // printf("sflphone_place_call :: c->accountID : %i \n",c->accountID); // account_t * current = c->accountID; - + + if( current ) { + if(g_strcasecmp(g_hash_table_lookup( current->properties, "Status"),"REGISTERED")==0) { // OK, everything alright - the call is made with the current account @@ -734,6 +740,7 @@ sflphone_place_call ( call_t * c ) } else { + // No current accounts have been setup. // So we place a call with the first registered account // and we change the current account @@ -756,6 +763,7 @@ sflphone_place_call ( call_t * c ) void sflphone_display_selected_codec (const gchar* codecName) { + call_t * selectedCall = call_get_selected(current_calls); gchar* msg; account_t* acc; @@ -871,7 +879,5 @@ void format_phone_number (gchar **number) { _number = *number; - // strip_spaces (&_number); - - + //strip_spaces (&_number); } diff --git a/sflphone-gtk/src/addressbook-config.c b/sflphone-gtk/src/addressbook-config.c index 3edc93265b2fbf92995fb777f2c352995bd0a016..4b2ae63008389d0050604ffbefc2f4be633376ab 100644 --- a/sflphone-gtk/src/addressbook-config.c +++ b/sflphone-gtk/src/addressbook-config.c @@ -94,7 +94,7 @@ static void search_phone_mobile_cb (GtkWidget *widget) { GtkWidget* create_addressbook_settings () { - GtkWidget *ret, *result_frame, *box, *value, *label, *photo, *item; + GtkWidget *ret, *result_frame, *table, *value, *label, *photo, *item; // Load the user value addressbook_load_parameters (&addressbook_config); @@ -106,44 +106,46 @@ GtkWidget* create_addressbook_settings () { gtk_box_pack_start(GTK_BOX(ret), result_frame, FALSE, FALSE, 0); gtk_widget_show (result_frame); - box = gtk_vbox_new( FALSE , 1); - gtk_widget_show (box); - gtk_container_add (GTK_CONTAINER(result_frame) , box); + table = gtk_table_new ( 5, 3, FALSE/* homogeneous */); + gtk_table_set_row_spacings( GTK_TABLE(table), 10); + gtk_table_set_col_spacings( GTK_TABLE(table), 10); + gtk_widget_show(table); + gtk_container_add( GTK_CONTAINER (result_frame) , table ); // SCALE BUTTON - NUMBER OF RESULTS label = gtk_label_new (_("Maximum result number for a request: ")); - gtk_box_pack_start (GTK_BOX(box) , label , FALSE , FALSE , 1); + gtk_table_attach ( GTK_TABLE( table ), label, 0, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10); value = gtk_hscale_new_with_range (25.0 , 50.0 , 5.0); gtk_label_set_mnemonic_widget (GTK_LABEL (label), value); gtk_scale_set_digits (GTK_SCALE(value) , 0); gtk_scale_set_value_pos (GTK_SCALE(value) , GTK_POS_RIGHT); gtk_range_set_value (GTK_RANGE( value ) , addressbook_config->max_results); - gtk_box_pack_start (GTK_BOX(box) , value , TRUE , TRUE , 0); g_signal_connect (G_OBJECT (value) , "value-changed" , G_CALLBACK(max_results_cb), NULL ); + gtk_table_attach ( GTK_TABLE( table ), value, 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); // PHOTO DISPLAY photo = gtk_check_button_new_with_mnemonic( _("_Display contact photo if available")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(photo), addressbook_config->display_contact_photo); g_signal_connect (G_OBJECT(photo) , "clicked" , G_CALLBACK (display_contact_photo_cb), NULL); - gtk_box_pack_start (GTK_BOX(box) , photo , TRUE , TRUE , 1); + gtk_table_attach ( GTK_TABLE( table ), photo, 0, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); label = gtk_label_new (_("Search for and display: ")); - gtk_box_pack_start (GTK_BOX(box) , label , FALSE , FALSE , 1); + gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); item = gtk_check_button_new_with_mnemonic( _("_Business phone")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(item), addressbook_config->search_phone_business); g_signal_connect (G_OBJECT(item) , "clicked" , G_CALLBACK (search_phone_business_cb) , NULL); - gtk_box_pack_start (GTK_BOX(box) , item , TRUE , TRUE , 1); + gtk_table_attach ( GTK_TABLE( table ), item, 1, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); item = gtk_check_button_new_with_mnemonic( _("_Home phone")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(item), addressbook_config->search_phone_home); g_signal_connect (G_OBJECT(item) , "clicked" , G_CALLBACK (search_phone_home_cb) , NULL); - gtk_box_pack_start (GTK_BOX(box) , item , TRUE , TRUE , 1); + gtk_table_attach ( GTK_TABLE( table ), item, 1, 3, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); item = gtk_check_button_new_with_mnemonic( _("_Mobile phone")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(item), addressbook_config->search_phone_mobile); g_signal_connect (G_OBJECT(item) , "clicked" , G_CALLBACK (search_phone_mobile_cb) , NULL); - gtk_box_pack_start (GTK_BOX(box) , item , TRUE , TRUE , 1); + gtk_table_attach ( GTK_TABLE( table ), item, 1, 3, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10); gtk_widget_show_all(ret); diff --git a/sflphone-gtk/src/calllist.h b/sflphone-gtk/src/calllist.h index bfd773263bc7bf227f8341f15878723092b3ffd6..a4f63806eba764779f2b7646027b7e2b116d7cb3 100644 --- a/sflphone-gtk/src/calllist.h +++ b/sflphone-gtk/src/calllist.h @@ -119,6 +119,9 @@ typedef struct { GtkWidget* view; GtkWidget* tree; + GtkWidget* searchbar; + // GtkTreeModel* histfilter; + // Calllist vars GQueue* callQueue; call_t* selectedCall; diff --git a/sflphone-gtk/src/calltab.c b/sflphone-gtk/src/calltab.c index 1ec9a9a95d357d03fa90fc93a8729924d0a6b020..8ed40db848251de1bc8b5fc8a4a9c94c07685649 100644 --- a/sflphone-gtk/src/calltab.c +++ b/sflphone-gtk/src/calltab.c @@ -24,7 +24,7 @@ #include <calltab.h> calltab_t* -calltab_init() +calltab_init(gchar* searchbar_type) { calltab_t* ret; @@ -33,11 +33,14 @@ calltab_init() ret->store = NULL; ret->view = NULL; ret->tree = NULL; + ret->searchbar = NULL; ret->callQueue = NULL; ret->selectedCall = NULL; + // ret->histfilter = NULL; - create_call_tree(ret); + create_call_tree(ret, searchbar_type); call_list_init(ret); + return ret; } diff --git a/sflphone-gtk/src/calltab.h b/sflphone-gtk/src/calltab.h index d3b85ca977f85f159ae9e13dafb44d1a25f09d9b..4438d3d8fcb2810be0948c3a4f0144f0698edc71 100644 --- a/sflphone-gtk/src/calltab.h +++ b/sflphone-gtk/src/calltab.h @@ -23,8 +23,8 @@ #include <calllist.h> #include <gtk/gtk.h> -//GtkTreeModel* histfilter; +GtkTreeModel* histfilter; -calltab_t* calltab_init(); +calltab_t* calltab_init(gchar* searchbar_type); #endif diff --git a/sflphone-gtk/src/calltree.c b/sflphone-gtk/src/calltree.c index f0f1fdfdeca03d9fb872b338d7771a7d57edfc3a..ab6cbfa05cc68149bd19ebc4d2a737e61d6fe65c 100644 --- a/sflphone-gtk/src/calltree.c +++ b/sflphone-gtk/src/calltree.c @@ -25,6 +25,7 @@ #include <actions.h> #include <calltree.h> #include <calllist.h> +#include <calltab.h> #include <menus.h> #include <dbus.h> #include <contactlist/eds.h> @@ -95,6 +96,7 @@ button_pressed(GtkWidget* widget, GdkEventButton *event, gpointer user_data UNUS static void call_button( GtkWidget *widget UNUSED, gpointer data UNUSED) { + g_print("------ call_button ----- \n"); call_t * selectedCall; call_t* new_call; gchar *to, *from; @@ -377,6 +379,7 @@ toolbar_update_buttons () static void selected(GtkTreeSelection *sel, void* data UNUSED ) { + g_print("---- selected --- \n"); GtkTreeIter iter; GValue val; GtkTreeModel *model = (GtkTreeModel*)active_calltree->store; @@ -604,7 +607,7 @@ reset_call_tree (calltab_t* tab) } void -create_call_tree (calltab_t* tab) + create_call_tree (calltab_t* tab, gchar* searchbar_type) { GtkWidget *sw; GtkCellRenderer *rend; @@ -665,13 +668,24 @@ create_call_tree (calltab_t* tab) NULL); gtk_box_pack_start(GTK_BOX(tab->tree), sw, TRUE, TRUE, 0); + + // no search bar if tab is either "history" or "addressbook" + if(searchbar_type){ + create_searchbar(tab,searchbar_type); + gtk_box_pack_start(GTK_BOX(tab->tree), tab->searchbar, FALSE, TRUE, 0); + } gtk_widget_show(tab->tree); + + // gtk_widget_show(tab->searchbar); + //toolbar_update_buttons(); } + + void update_call_tree_remove (calltab_t* tab, call_t * c) { @@ -826,6 +840,21 @@ update_call_tree (calltab_t* tab, call_t * c) toolbar_update_buttons(); } +void +create_searchbar(calltab_t* tab, gchar* searchbar_type) +{ + // g_strcmp0 returns 0 if str1 == str2 + if(g_strcmp0(searchbar_type,"history") == 0){ + + tab->searchbar = create_filter_entry_history(); + + } + + else if(g_strcmp0(searchbar_type,"contacts") == 0) + tab->searchbar = create_filter_entry_contact(); + +} + void update_call_tree_add (calltab_t* tab, call_t * c) { diff --git a/sflphone-gtk/src/calltree.h b/sflphone-gtk/src/calltree.h index f307116040084dc7f11aaca0681bf7feb7e41b9c..dd1de4d91a467c2f919f84376b53586e1e6462d6 100644 --- a/sflphone-gtk/src/calltree.h +++ b/sflphone-gtk/src/calltree.h @@ -31,7 +31,8 @@ * @brief The GtkTreeView that list calls in the main window. */ -GtkWidget * filter_entry; +GtkWidget * filter_entry_contact; +GtkWidget * filter_entry_history; calltab_t* active_calltree; @@ -41,7 +42,7 @@ void free_call_t (call_t *c); * Create a new widget calltree * @return GtkWidget* A new widget */ -void create_call_tree(calltab_t* tab); +void create_call_tree(calltab_t* tab, gchar* searchbar_type); /** * Update the toolbar's buttons state, according to the call state @@ -73,8 +74,14 @@ void reset_call_tree (calltab_t* tab); */ GtkWidget * create_toolbar(); +GtkWidget * create_filter_entry(); + +GtkTreeModel * create_filter (GtkTreeModel* child); + void display_calltree (calltab_t *tab); +void create_searchbar(calltab_t* tab, gchar* searchbar_type); + void create_new_entry_in_contactlist (gchar *contact_name, gchar *contact_phone, contact_type_t type, GdkPixbuf *photo); #endif diff --git a/sflphone-gtk/src/configurationmanager-glue.h b/sflphone-gtk/src/configurationmanager-glue.h index 194b6f27be4b6511492afa23c77d8b40d12f0ba0..7d29e92172ab1c6cba9e07cec330c23b5d26254c 100644 --- a/sflphone-gtk/src/configurationmanager-glue.h +++ b/sflphone-gtk/src/configurationmanager-glue.h @@ -2300,6 +2300,81 @@ org_sflphone_SFLphone_ConfigurationManager_set_addressbook_settings_async (DBusG stuff->userdata = userdata; return dbus_g_proxy_begin_call (proxy, "setAddressbookSettings", org_sflphone_SFLphone_ConfigurationManager_set_addressbook_settings_async_callback, stuff, g_free, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_INT), IN_settings, G_TYPE_INVALID); } +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +org_sflphone_SFLphone_ConfigurationManager_get_hook_settings (DBusGProxy *proxy, GHashTable** OUT_settings, GError **error) + +{ + return dbus_g_proxy_call (proxy, "getHookSettings", error, G_TYPE_INVALID, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING), OUT_settings, G_TYPE_INVALID); +} + +typedef void (*org_sflphone_SFLphone_ConfigurationManager_get_hook_settings_reply) (DBusGProxy *proxy, GHashTable *OUT_settings, GError *error, gpointer userdata); + +static void +org_sflphone_SFLphone_ConfigurationManager_get_hook_settings_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + GHashTable* OUT_settings; + dbus_g_proxy_end_call (proxy, call, &error, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING), &OUT_settings, G_TYPE_INVALID); + (*(org_sflphone_SFLphone_ConfigurationManager_get_hook_settings_reply)data->cb) (proxy, OUT_settings, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +org_sflphone_SFLphone_ConfigurationManager_get_hook_settings_async (DBusGProxy *proxy, org_sflphone_SFLphone_ConfigurationManager_get_hook_settings_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_new (DBusGAsyncData, 1); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "getHookSettings", org_sflphone_SFLphone_ConfigurationManager_get_hook_settings_async_callback, stuff, g_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +org_sflphone_SFLphone_ConfigurationManager_set_hook_settings (DBusGProxy *proxy, const GHashTable* IN_settings, GError **error) + +{ + return dbus_g_proxy_call (proxy, "setHookSettings", error, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING), IN_settings, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*org_sflphone_SFLphone_ConfigurationManager_set_hook_settings_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +org_sflphone_SFLphone_ConfigurationManager_set_hook_settings_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(org_sflphone_SFLphone_ConfigurationManager_set_hook_settings_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +org_sflphone_SFLphone_ConfigurationManager_set_hook_settings_async (DBusGProxy *proxy, const GHashTable* IN_settings, org_sflphone_SFLphone_ConfigurationManager_set_hook_settings_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_new (DBusGAsyncData, 1); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setHookSettings", org_sflphone_SFLphone_ConfigurationManager_set_hook_settings_async_callback, stuff, g_free, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING), IN_settings, G_TYPE_INVALID); +} #endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_org_sflphone_SFLphone_ConfigurationManager */ G_END_DECLS diff --git a/sflphone-gtk/src/configwindow.c b/sflphone-gtk/src/configwindow.c index 81063f99aa69c8020d0464c99f56a06df48b6b4e..60e6787c828aa7f6a901a387673c170fed5baaac 100644 --- a/sflphone-gtk/src/configwindow.c +++ b/sflphone-gtk/src/configwindow.c @@ -29,6 +29,7 @@ #include <mainwindow.h> #include <audioconf.h> #include <addressbook-config.h> +#include <hooks-config.h> #include <stdlib.h> #include <stdio.h> @@ -479,7 +480,7 @@ void update_registration( void ) GtkWidget* create_stun_tab() { GtkWidget * tableNat; - gchar * stun_server= "stun.fwdnet.net:3478"; + gchar * stun_server= "stun.ekiga.net:3478"; gchar * stun_enabled = "FALSE"; GtkWidget * label; @@ -781,6 +782,11 @@ show_config_window () gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new(_("Address Book"))); gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab); + // HookS tab + tab = create_hooks_settings(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new(_("Hooks"))); + gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab); + gtk_notebook_set_current_page( GTK_NOTEBOOK( notebook) , 1); result = gtk_dialog_run(dialog); @@ -856,5 +862,6 @@ void config_window_set_stun_visible() void save_configuration_parameters (void) { addressbook_save_parameters (); + hooks_save_parameters (); } diff --git a/sflphone-gtk/src/contactlist/Makefile.am b/sflphone-gtk/src/contactlist/Makefile.am index d8fee4636b19b1bd2d28abe3d21b7753647c0412..d603d369c831b92052444431560433b399f92747 100644 --- a/sflphone-gtk/src/contactlist/Makefile.am +++ b/sflphone-gtk/src/contactlist/Makefile.am @@ -3,6 +3,6 @@ noinst_LTLIBRARIES = libcontact.la libcontact_la_SOURCES = \ eds.c -libcontact_la_LDFLAGS= -pthread -lebook-1.2 -lgnome-2 -lpopt -ledataserver-1.2 -lxml2 -lgconf-2 -lsoup-2.4 -lbonobo-2 -lbonobo-activation -lORBit-2 -lgthread-2.0 -lrt -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lpangoft2-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lgio-2.0 -lcairo -lpango-1.0 -lfreetype -lz -lfontconfig -lgmodule-2.0 -lgobject-2.0 -lglib-2.0 - -libcontact_la_CFLAGS=-DORBIT2=1 -pthread -I/usr/include/evolution-data-server-2.24 -I/usr/include/libbonobo-2.0 -I/usr/include/libgnome-2.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/orbit-2.0 -I/usr/include/bonobo-activation-2.0 -I/usr/include/gconf/2 -I/usr/include/gnome-vfs-2.0 -I/usr/lib/gnome-vfs-2.0/include -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/libxml2 -I/usr/include/libsoup-2.4 -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/pygtk-2.0 +libcontact_la_LDFLAGS=@DEPS_LDFLAGS@ + +libcontact_la_CFLAGS=@DEPS_CFLAGS@ diff --git a/sflphone-gtk/src/dbus.c b/sflphone-gtk/src/dbus.c index 52902adeb15a6142af5a8ab109db077b012b3c32..580c50dc284d0cef71ad5358ea7549f5f61be4f7 100644 --- a/sflphone-gtk/src/dbus.c +++ b/sflphone-gtk/src/dbus.c @@ -1138,7 +1138,7 @@ dbus_get_is_recording(const call_t * c) { g_error_free(error); } - g_print("RECORDING: %i \n",isRecording); + //g_print("RECORDING: %i \n",isRecording); return isRecording; } @@ -1497,4 +1497,31 @@ void dbus_set_addressbook_settings (GHashTable * settings){ } } +GHashTable* dbus_get_hook_settings (void) { + + GError *error = NULL; + GHashTable *results = NULL; + + //g_print ("Calling org_sflphone_SFLphone_ConfigurationManager_get_addressbook_settings\n"); + + org_sflphone_SFLphone_ConfigurationManager_get_hook_settings (configurationManagerProxy, &results, &error); + if (error){ + g_print ("Error calling org_sflphone_SFLphone_ConfigurationManager_get_hook_settings\n"); + g_error_free (error); + } + + return results; +} + +void dbus_set_hook_settings (GHashTable * settings){ + + GError *error = NULL; + + org_sflphone_SFLphone_ConfigurationManager_set_hook_settings (configurationManagerProxy, settings, &error); + if (error){ + g_print ("Error calling org_sflphone_SFLphone_ConfigurationManager_set_hook_settings\n"); + g_error_free (error); + } +} + diff --git a/sflphone-gtk/src/dbus.h b/sflphone-gtk/src/dbus.h index 7eac089d8ae3d9768301b2ac134e5cb77e10eb4f..946c65486186c9103c73ed52e70c589223bb1814 100644 --- a/sflphone-gtk/src/dbus.h +++ b/sflphone-gtk/src/dbus.h @@ -458,6 +458,18 @@ GHashTable* dbus_get_addressbook_settings (void); */ void dbus_set_addressbook_settings (GHashTable *); +/** + * Encapsulate all the url hook-related configuration + * Get the configuration + */ +GHashTable* dbus_get_hook_settings (void); + +/** + * Encapsulate all the url hook-related configuration + * Set the configuration + */ +void dbus_set_hook_settings (GHashTable *); + diff --git a/sflphone-gtk/src/hooks-config.c b/sflphone-gtk/src/hooks-config.c new file mode 100644 index 0000000000000000000000000000000000000000..b4ede224d6e7542f9fbd087b60fb3e878608b7e9 --- /dev/null +++ b/sflphone-gtk/src/hooks-config.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "hooks-config.h" + +URLHook_Config *_urlhook_config; + +GtkWidget *field, *command; + +void hooks_load_parameters (URLHook_Config** settings){ + + GHashTable *_params = NULL; + URLHook_Config *_settings; + + // Allocate a struct + _settings = g_new0 (URLHook_Config, 1); + + // Fetch the settings from D-Bus + _params = (GHashTable*) dbus_get_hook_settings (); + + if (_params == NULL) { + _settings->sip_field = DEFAULT_SIP_URL_FIELD; + _settings->command = DEFAULT_URL_COMMAND; + _settings->sip_enabled = "0"; + } + else { + _settings->sip_field = (gchar*)(g_hash_table_lookup (_params, URLHOOK_SIP_FIELD)); + _settings->command = (gchar*)(g_hash_table_lookup (_params, URLHOOK_COMMAND)); + _settings->sip_enabled = (gchar*)(g_hash_table_lookup (_params, URLHOOK_SIP_ENABLED)); + } + + *settings = _settings; +} + + +void hooks_save_parameters (void){ + + GHashTable *params = NULL; + + params = g_hash_table_new (NULL, g_str_equal); + g_hash_table_replace (params, (gpointer)URLHOOK_SIP_FIELD, + g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(field)))); + g_hash_table_replace (params, (gpointer)URLHOOK_COMMAND, + g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(command)))); + g_hash_table_replace (params, (gpointer)URLHOOK_SIP_ENABLED, + (gpointer)g_strdup(_urlhook_config->sip_enabled)); + + dbus_set_hook_settings (params); + + // Decrement the reference count + g_hash_table_unref (params); + +} + +static void sip_enabled_cb (GtkWidget *widget) { + + guint check; + + check = (guint) gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)); + if (check) + _urlhook_config->sip_enabled="1"; + else + _urlhook_config->sip_enabled="0"; +} + +GtkWidget* create_hooks_settings (){ + + GtkWidget *ret, *url_frame, *table, *label; + + // Load the user value + hooks_load_parameters (&_urlhook_config); + + ret = gtk_vbox_new(FALSE, 10); + gtk_container_set_border_width(GTK_CONTAINER(ret), 10); + + url_frame = gtk_frame_new(_("URL argument")); + gtk_box_pack_start(GTK_BOX(ret), url_frame, FALSE, FALSE, 0); + gtk_widget_show (url_frame); + + table = gtk_table_new ( 5, 2, FALSE/* homogeneous */); + gtk_table_set_row_spacings( GTK_TABLE(table), 10); + gtk_table_set_col_spacings( GTK_TABLE(table), 10); + gtk_widget_show(table); + gtk_container_add( GTK_CONTAINER (url_frame) , table ); + + field = gtk_check_button_new_with_mnemonic( _("_SIP protocol")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(field), (g_strcasecmp (_urlhook_config->sip_enabled, "1")==0)?TRUE:FALSE); + g_signal_connect (G_OBJECT(field) , "clicked" , G_CALLBACK (sip_enabled_cb), NULL); + gtk_table_attach ( GTK_TABLE( table ), field, 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + field = gtk_check_button_new_with_mnemonic( _("_IAX2 protocol")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(field), TRUE); + //g_signal_connect (G_OBJECT(field) , "clicked" , NULL, NULL); + gtk_table_attach ( GTK_TABLE( table ), field, 0, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_widget_set_sensitive (GTK_WIDGET (field), FALSE); + + label = gtk_label_new_with_mnemonic (_("_SIP Header: ")); + gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + field = gtk_entry_new (); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), field); + gtk_entry_set_text(GTK_ENTRY(field), _urlhook_config->sip_field); + gtk_table_attach ( GTK_TABLE( table ), field, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + label = gtk_label_new_with_mnemonic (_("_Command: ")); + gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + command = gtk_entry_new (); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), command); + gtk_entry_set_text(GTK_ENTRY(command), _urlhook_config->command); + gtk_table_attach ( GTK_TABLE( table ), command, 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10); + + gtk_widget_show_all(ret); + + return ret; +} diff --git a/sflphone-gtk/src/hooks-config.h b/sflphone-gtk/src/hooks-config.h new file mode 100644 index 0000000000000000000000000000000000000000..41ee59b718cc88938129305efe9b760aef24352a --- /dev/null +++ b/sflphone-gtk/src/hooks-config.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _HOOKS_CONFIG +#define _HOOKS_CONFIG + +#include <gtk/gtk.h> +#include <glib/gtypes.h> + +#include "actions.h" + +G_BEGIN_DECLS + +#define DEFAULT_SIP_URL_FIELD "X-sflphone-url" +#define DEFAULT_URL_COMMAND "x-www-browser" +#define URLHOOK_COMMAND "URLHOOK_COMMAND" +#define URLHOOK_SIP_FIELD "URLHOOK_SIP_FIELD" +#define URLHOOK_SIP_ENABLED "URLHOOK_SIP_ENABLED" + + +typedef struct _URLHook_Config { + gchar *sip_enabled; + gchar *sip_field; + gchar *command; +}URLHook_Config; + +/** + * Save the parameters through D-BUS + */ +void hooks_save_parameters (void); + +void hooks_load_parameters (URLHook_Config** settings); + +GtkWidget* create_hooks_settings (); + +G_END_DECLS + +#endif // _HOOKS_CONFIG diff --git a/sflphone-gtk/src/main.c b/sflphone-gtk/src/main.c index 886f523186bd176b06f1e99c8724d811decdf251..b3c92c07315d4765c13d28c82ffad85591efd6c2 100644 --- a/sflphone-gtk/src/main.c +++ b/sflphone-gtk/src/main.c @@ -33,7 +33,7 @@ main (int argc, char *argv[]) gtk_init (&argc, &argv); g_print("%s\n", PACKAGE_STRING); - g_print("Copyright (c) 2005 2006 2007 2008 Savoir-faire Linux Inc.\n"); + g_print("Copyright (c) 2005 2006 2007 2008 2009 Savoir-faire Linux Inc.\n"); g_print("This is free software. You may redistribute copies of it under the terms of\n\ the GNU General Public License Version 3 <http://www.gnu.org/licenses/gpl.html>.\n\ There is NO WARRANTY, to the extent permitted by law.\n\n"); diff --git a/sflphone-gtk/src/mainwindow.c b/sflphone-gtk/src/mainwindow.c index e0c63ab3bfcaa8841cb3cbda584421e97cdca9e5..4473a53176133923eff6fda2f3dd2b4e146c42bf 100644 --- a/sflphone-gtk/src/mainwindow.c +++ b/sflphone-gtk/src/mainwindow.c @@ -135,13 +135,19 @@ create_main_window () gtk_box_pack_start (GTK_BOX (vbox), history->tree, TRUE /*expand*/, TRUE /*fill*/, 0 /*padding*/); gtk_box_pack_start (GTK_BOX (vbox), contacts->tree, TRUE /*expand*/, TRUE /*fill*/, 0 /*padding*/); + // gtk_box_pack_start (GTK_BOX (vbox), current_calls->searchbar, TRUE /*expand*/, TRUE /*fill*/, 0 /*padding*/); + // gtk_box_pack_start (GTK_BOX (vbox), history->searchbar, TRUE /*expand*/, TRUE /*fill*/, 0 /*padding*/); + // gtk_box_pack_start (GTK_BOX (vbox), contacts ->searchbar, TRUE /*expand*/, TRUE /*fill*/, 0 /*padding*/); + gtk_box_pack_start (GTK_BOX (vbox), subvbox, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/); - if( SHOW_SEARCHBAR ){ - filterEntry = create_filter_entry(); - gtk_box_pack_start (GTK_BOX (subvbox), filterEntry, FALSE /*expand*/, TRUE /*fill*/, 0 /*padding*/); - gtk_widget_show_all ( filterEntry ); - } + + // if( SHOW_SEARCHBAR ){ + // filterEntry = create_filter_entry(); + // gtk_box_pack_start (GTK_BOX (subvbox), filterEntry, FALSE /*expand*/, TRUE /*fill*/, 0 /*padding*/); + // gtk_widget_show_all ( filterEntry ); + // } + if( SHOW_VOLUME ){ speaker_control = create_slider("speaker"); @@ -175,7 +181,8 @@ create_main_window () /* don't show waiting layer */ gtk_widget_hide(waitingLayer); - //gtk_tree_view_set_model(GTK_TREE_VIEW(history->view), GTK_TREE_MODEL(histfilter)); + gtk_tree_view_set_model(GTK_TREE_VIEW(history->view), GTK_TREE_MODEL(histfilter)); + // Configuration wizard if (account_list_get_size() == 0) { @@ -280,15 +287,15 @@ void main_window_searchbar( gboolean *state ){ if( !SHOW_SEARCHBAR ) { - filterEntry = create_filter_entry(); - gtk_box_pack_start (GTK_BOX (subvbox), filterEntry, FALSE /*expand*/, TRUE /*fill*/, 0 /*padding*/); - gtk_widget_show_all (filterEntry); - *state = TRUE; + // filterEntry = create_filter_entry(); + // gtk_box_pack_start (GTK_BOX (subvbox), filterEntry, FALSE /*expand*/, TRUE /*fill*/, 0 /*padding*/); + // gtk_widget_show_all (filterEntry); + // *state = TRUE; } else { - gtk_container_remove( GTK_CONTAINER(subvbox) , filterEntry ); - *state = FALSE; + // gtk_container_remove( GTK_CONTAINER(subvbox) , filterEntry ); + // *state = FALSE; } } diff --git a/sflphone-gtk/src/menus.c b/sflphone-gtk/src/menus.c index e123483f4f06405f39e99765dab730dcc9a0deb8..2b367cbf5f85f6438fef6cea23f6c5b640424654 100644 --- a/sflphone-gtk/src/menus.c +++ b/sflphone-gtk/src/menus.c @@ -120,6 +120,7 @@ help_about ( void * foo UNUSED) "Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>", "Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>", "Yun Liu <yun.liu@savoirfairelinux.com>" + "Alexandre Savard <alexandre.savard@savoirfairelinux.com>", "Jean-Philippe Barrette-LaPierre", "Laurielle Lea", NULL}; @@ -324,7 +325,7 @@ create_call_menu() NULL); gtk_widget_show (menu_items); - image = gtk_tool_button_new_from_stock (GTK_STOCK_MEDIA_RECORD); + image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_RECORD, GTK_ICON_SIZE_MENU); recordMenu = gtk_image_menu_item_new_with_mnemonic(_("_Record")); gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM ( recordMenu ), image ); gtk_menu_shell_append (GTK_MENU_SHELL (menu), recordMenu); @@ -813,7 +814,7 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event) if(record) { menu_items = gtk_image_menu_item_new_with_mnemonic(_("_Record")); - image = gtk_tool_button_new_from_stock (GTK_STOCK_MEDIA_RECORD); + image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_RECORD, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_items), image); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items); g_signal_connect (G_OBJECT (menu_items), "activate", diff --git a/sflphone-gtk/src/searchfilter.c b/sflphone-gtk/src/searchfilter.c index 6adc6e2613b7c15f994eb44840289b28f7b0772a..1d62a7e0b8a686aa00b78c08a155fd244b4be4f5 100644 --- a/sflphone-gtk/src/searchfilter.c +++ b/sflphone-gtk/src/searchfilter.c @@ -45,7 +45,7 @@ gboolean is_visible (GtkTreeModel* model, GtkTreeIter* iter, gpointer data UNUSE GValue val; gchar* text = NULL; - gchar* search = (gchar*)gtk_entry_get_text(GTK_ENTRY(filter_entry)); + gchar* search = (gchar*)gtk_entry_get_text(GTK_ENTRY(filter_entry_history)); memset (&val, 0, sizeof(val)); gtk_tree_model_get_value(GTK_TREE_MODEL(model), iter, 1, &val); if(G_VALUE_HOLDS_STRING(&val)){ @@ -113,8 +113,8 @@ void filter_entry_changed (GtkEntry* entry, gchar* arg1 UNUSED, gpointer data UN AddressBook_Config *addressbook_config; /* Switch to the address book when the focus is on the search bar */ - if (active_calltree != contacts) - display_calltree (contacts); + // if (active_calltree != contacts) + // display_calltree (contacts); /* We want to search in the contact list */ @@ -136,27 +136,41 @@ void filter_entry_changed (GtkEntry* entry, gchar* arg1 UNUSED, gpointer data UN } -void clear_filter_entry_if_default (GtkWidget* widget UNUSED, gpointer user_data UNUSED) { +void +filter_entry_changed_history(GtkEntry* entry UNUSED, gchar* arg1 UNUSED, gpointer data UNUSED) +{ + g_print("--- filter_entry_changed_history --- \n"); - if(g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(filter_entry)), _("Search"), 6) == 0) - gtk_entry_set_text(GTK_ENTRY(filter_entry), ""); + if (active_calltree != history) + display_calltree (history); + // gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(historyButton), TRUE); + gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(histfilter)); + // gtk_tree_view_set_model(GTK_TREE_VIEW(history->view), GTK_TREE_MODEL(histfilter)); } -GtkWidget* create_filter_entry() { + +void clear_filter_entry_if_default (GtkWidget* widget, gpointer user_data UNUSED) { + + if(g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(widget)), _("Search"), 6) == 0) + gtk_entry_set_text(GTK_ENTRY(widget), ""); + +} + +GtkWidget* create_filter_entry_contact() { GtkWidget* image; GtkWidget* ret = gtk_hbox_new(FALSE, 0); - filter_entry = sexy_icon_entry_new(); + filter_entry_contact = sexy_icon_entry_new(); image = gtk_image_new_from_stock( GTK_STOCK_FIND , GTK_ICON_SIZE_SMALL_TOOLBAR); - sexy_icon_entry_set_icon( SEXY_ICON_ENTRY(filter_entry), SEXY_ICON_ENTRY_PRIMARY , GTK_IMAGE(image) ); - sexy_icon_entry_add_clear_button( SEXY_ICON_ENTRY(filter_entry) ); - gtk_entry_set_text(GTK_ENTRY(filter_entry), _("Search")); - g_signal_connect(GTK_ENTRY(filter_entry), "changed", G_CALLBACK(filter_entry_changed), NULL); - g_signal_connect(GTK_ENTRY(filter_entry), "grab-focus", G_CALLBACK(clear_filter_entry_if_default), NULL); + sexy_icon_entry_set_icon( SEXY_ICON_ENTRY(filter_entry_contact), SEXY_ICON_ENTRY_PRIMARY , GTK_IMAGE(image) ); + sexy_icon_entry_add_clear_button( SEXY_ICON_ENTRY(filter_entry_contact) ); + gtk_entry_set_text(GTK_ENTRY(filter_entry_contact), _("Search")); + g_signal_connect(GTK_ENTRY(filter_entry_contact), "changed", G_CALLBACK(filter_entry_changed), NULL); + g_signal_connect(GTK_ENTRY(filter_entry_contact), "grab-focus", G_CALLBACK(clear_filter_entry_if_default), NULL); - gtk_box_pack_start(GTK_BOX(ret), filter_entry, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(ret), filter_entry_contact, TRUE, TRUE, 0); // Create waiting icon waitingPixOn = gdk_pixbuf_animation_new_from_file(ICONS_DIR "/wait-on.gif", NULL); @@ -167,6 +181,36 @@ GtkWidget* create_filter_entry() { } + +GtkWidget* create_filter_entry_history() { + + g_print("--- create_filter_entry_history --- \n"); + + GtkWidget* image; + GtkWidget* ret = gtk_hbox_new(FALSE, 0); + + filter_entry_history = sexy_icon_entry_new(); + image = gtk_image_new_from_stock( GTK_STOCK_FIND , GTK_ICON_SIZE_SMALL_TOOLBAR); + sexy_icon_entry_set_icon( SEXY_ICON_ENTRY(filter_entry_history), SEXY_ICON_ENTRY_PRIMARY , GTK_IMAGE(image) ); + sexy_icon_entry_add_clear_button( SEXY_ICON_ENTRY(filter_entry_history) ); + gtk_entry_set_text(GTK_ENTRY(filter_entry_history), _("Search")); + g_signal_connect(GTK_ENTRY(filter_entry_history), "changed", G_CALLBACK(filter_entry_changed_history), NULL); + g_signal_connect(GTK_ENTRY(filter_entry_history), "grab-focus", G_CALLBACK(clear_filter_entry_if_default), NULL); + + gtk_box_pack_start(GTK_BOX(ret), filter_entry_history, TRUE, TRUE, 0); + + // Create waiting icon + //waitingPixOn = gdk_pixbuf_animation_new_from_file(ICONS_DIR "/wait-on.gif", NULL); + //waitingPixOff = gdk_pixbuf_new_from_file(ICONS_DIR "/wait-off.gif", NULL); + //waitingLayer = gtk_image_new_from_pixbuf(waitingPixOff); + + //gtk_box_pack_end(GTK_BOX(ret), waitingLayer, TRUE, TRUE, 0); + + + return ret; + +} + void activateWaitingLayer() { gtk_widget_show(waitingLayer); } diff --git a/sflphone-gtk/src/searchfilter.h b/sflphone-gtk/src/searchfilter.h index cfceaa9a68b2784a6258c89523234f0823120708..c470acab847ae76a21063fb267cdfd52ba26994b 100644 --- a/sflphone-gtk/src/searchfilter.h +++ b/sflphone-gtk/src/searchfilter.h @@ -36,7 +36,9 @@ GtkTreeModel* create_filter(GtkTreeModel* child); gboolean is_visible(GtkTreeModel* model, GtkTreeIter* iter, gpointer data); -GtkWidget* create_filter_entry(); +GtkWidget* create_filter_entry_contact(); + +GtkWidget* create_filter_entry_history(); void activateWaitingLayer(); diff --git a/sflphone-gtk/view b/sflphone-gtk/view new file mode 100644 index 0000000000000000000000000000000000000000..1552fda6f631d91a7db39092156ab4fc51ff47b1 --- /dev/null +++ b/sflphone-gtk/view @@ -0,0 +1,6 @@ +src/actions.c: if(SHOW_SEARCHBAR) histfilter = create_filter(GTK_TREE_MODEL(history->store)); +src/calltree.c: gtk_widget_hide(history->tree); +src/calltree.c: gtk_widget_show(history->tree); +src/mainwindow.c: gtk_box_pack_start (GTK_BOX (vbox), history->tree, TRUE /*expand*/, TRUE /*fill*/, 0 /*padding*/); +src/mainwindow.c: gtk_widget_hide(history->tree); +src/mainwindow.c: gtk_tree_view_set_model(GTK_TREE_VIEW(history->view), GTK_TREE_MODEL(histfilter)); diff --git a/src/Makefile.am b/src/Makefile.am index 62b16508816ef09325ff14cbc183059016e7c9b7..9269904f4f05c823b2dd8991663bd5c1ccc43c88 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,7 @@ IAXSOURCES = IAXHEADERS = endif -SUBDIRS = audio config dbus plug-in +SUBDIRS = audio config dbus plug-in hooks # Add here the cpp files to be build with sflphone sflphoned_SOURCES = \ @@ -50,8 +50,7 @@ sflphoned_LDADD = \ @CCRTP_LIBS@ \ @ALSA_LIBS@ \ @PULSEAUDIO_LIBS@ \ - @SAMPLERATE_LIBS@ \ - @LIBOPENSSL_LIBS@ + @SAMPLERATE_LIBS@ # sflphoned_LDFLAGS= -pg -luuid sflphoned_LDFLAGS= -luuid @@ -84,6 +83,7 @@ libsflphone_la_LIBADD = \ ./config/libconfig.la \ ./plug-in/libplugin.la \ ./plug-in/audiorecorder/libaudiorecorder.la \ + ./hooks/libhooks.la \ $(IAX_LIBS) libsflphone_la_SOURCES = diff --git a/src/dbus/configurationmanager-glue.h b/src/dbus/configurationmanager-glue.h index 3c9eacbf7a2558bafadec844bb1056c7939a9211..04be0e595d1cbd39097ba114fc4973ba708ef5e2 100644 --- a/src/dbus/configurationmanager-glue.h +++ b/src/dbus/configurationmanager-glue.h @@ -81,6 +81,8 @@ public: register_method(ConfigurationManager_adaptor, isStunEnabled, _isStunEnabled_stub); register_method(ConfigurationManager_adaptor, getAddressbookSettings, _getAddressbookSettings_stub); register_method(ConfigurationManager_adaptor, setAddressbookSettings, _setAddressbookSettings_stub); + register_method(ConfigurationManager_adaptor, getHookSettings, _getHookSettings_stub); + register_method(ConfigurationManager_adaptor, setHookSettings, _setHookSettings_stub); } ::DBus::IntrospectedInterface *const introspect() const @@ -385,6 +387,16 @@ public: { "settings", "a{si}", true }, { 0, 0, 0 } }; + static ::DBus::IntrospectedArgument getHookSettings_args[] = + { + { "settings", "a{ss}", false }, + { 0, 0, 0 } + }; + static ::DBus::IntrospectedArgument setHookSettings_args[] = + { + { "settings", "a{ss}", true }, + { 0, 0, 0 } + }; static ::DBus::IntrospectedArgument parametersChanged_args[] = { { "list", "a{ss}", false }, @@ -462,6 +474,8 @@ public: { "isStunEnabled", isStunEnabled_args }, { "getAddressbookSettings", getAddressbookSettings_args }, { "setAddressbookSettings", setAddressbookSettings_args }, + { "getHookSettings", getHookSettings_args }, + { "setHookSettings", setHookSettings_args }, { 0, 0 } }; static ::DBus::IntrospectedMethod ConfigurationManager_adaptor_signals[] = @@ -557,6 +571,8 @@ public: virtual int32_t isStunEnabled() = 0; virtual std::map< std::string, int32_t > getAddressbookSettings() = 0; virtual void setAddressbookSettings(const std::map< std::string, int32_t >& settings) = 0; + virtual std::map< std::string, std::string > getHookSettings() = 0; + virtual void setHookSettings(const std::map< std::string, std::string >& settings) = 0; public: @@ -1165,6 +1181,25 @@ private: ::DBus::ReturnMessage reply(call); return reply; } + ::DBus::Message _getHookSettings_stub(const ::DBus::CallMessage &call) + { + ::DBus::MessageIter ri = call.reader(); + + std::map< std::string, std::string > argout1 = getHookSettings(); + ::DBus::ReturnMessage reply(call); + ::DBus::MessageIter wi = reply.writer(); + wi << argout1; + return reply; + } + ::DBus::Message _setHookSettings_stub(const ::DBus::CallMessage &call) + { + ::DBus::MessageIter ri = call.reader(); + + std::map< std::string, std::string > argin1; ri >> argin1; + setHookSettings(argin1); + ::DBus::ReturnMessage reply(call); + return reply; + } }; } } } diff --git a/src/dbus/configurationmanager-introspec.xml b/src/dbus/configurationmanager-introspec.xml index 6f897c2c2a0fd1082fa27fd4534bc3ac34f3c45c..8d70715421349075ee286676f699ba19fd546157 100644 --- a/src/dbus/configurationmanager-introspec.xml +++ b/src/dbus/configurationmanager-introspec.xml @@ -251,6 +251,15 @@ <arg type="a{si}" name="settings" direction="in"/> </method> + <!-- Hook configuration --> + <method name="getHookSettings"> + <arg type="a{ss}" name="settings" direction="out"/> + </method> + + <method name="setHookSettings"> + <arg type="a{ss}" name="settings" direction="in"/> + </method> + <!-- ///////////////////////////// --> <signal name="parametersChanged"> <arg type="a{ss}" name="list" direction="out"/> diff --git a/src/dbus/configurationmanager.cpp b/src/dbus/configurationmanager.cpp index ac26ec4a42491e654ec61ef4e14c1aad2a207382..78a6a490a7d23521a3afac2bae6c8275aa1c3821 100644 --- a/src/dbus/configurationmanager.cpp +++ b/src/dbus/configurationmanager.cpp @@ -433,3 +433,11 @@ std::map<std::string, int32_t> ConfigurationManager::getAddressbookSettings (voi void ConfigurationManager::setAddressbookSettings (const std::map<std::string, int32_t>& settings) { Manager::instance().setAddressbookSettings (settings); } + +std::map<std::string,std::string> ConfigurationManager::getHookSettings (void) { + return Manager::instance().getHookSettings (); +} + +void ConfigurationManager::setHookSettings (const std::map<std::string, std::string>& settings) { + Manager::instance().setHookSettings (settings); +} diff --git a/src/dbus/configurationmanager.h b/src/dbus/configurationmanager.h index ebbc728d1d99807b4f7d106f2fd8033af4d3d6d6..82a962728fe00324127831dcc6ae96fbd8565cc6 100644 --- a/src/dbus/configurationmanager.h +++ b/src/dbus/configurationmanager.h @@ -107,6 +107,9 @@ public: std::map<std::string, int32_t> getAddressbookSettings (void); void setAddressbookSettings (const std::map<std::string, int32_t>& settings); + std::map<std::string, std::string> getHookSettings (void); + void setHookSettings (const std::map<std::string, std::string>& settings); + }; diff --git a/src/global.h b/src/global.h index 334c18edfe4abf704b1b3d34a776da6bbd966e0f..406e2b855b572e5ff5633a39054c115214f73855 100644 --- a/src/global.h +++ b/src/global.h @@ -32,7 +32,7 @@ #include <map> #include <vector> -#define SFLPHONED_VERSION "0.9.3" /** Version number */ +#define SFLPHONED_VERSION "0.9.4" /** Version number */ #define HOMEDIR (getenv ("HOME")) /** Home directory */ @@ -135,4 +135,8 @@ static const SOUND_FORMAT INT32 = 0x8; #define DEFAULT_SIP_PORT 5060 +#define HOOK_DEFAULT_SIP_FIELD "X-sflphone-url" +#define HOOK_DEFAULT_URL_COMMAND "x-www-browser" + + #endif // __GLOBAL_H__ diff --git a/src/hooks/Makefile.am b/src/hooks/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..aa5797fe7a723e97055388356c1b3d8bb82aea32 --- /dev/null +++ b/src/hooks/Makefile.am @@ -0,0 +1,6 @@ +SUBDIRS = + +noinst_LTLIBRARIES = libhooks.la + +libhooks_la_SOURCES = \ + urlhook.cpp urlhook.h diff --git a/src/hooks/urlhook.cpp b/src/hooks/urlhook.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a5e63b3190cf39601f58e1296608f6139c976d2 --- /dev/null +++ b/src/hooks/urlhook.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "urlhook.h" +#include <iostream> + +UrlHook::UrlHook () { } + +UrlHook::~UrlHook () { } + +void UrlHook::addAction (std::string field_value, std::string command){ + + std::string command_bg; + + /* Execute the command in the background to not block the application */ + command_bg = command + " " + field_value + "&" ; + /* Execute a system call */ + RUN_COMMAND (command_bg.c_str()); +} + + diff --git a/src/hooks/urlhook.h b/src/hooks/urlhook.h new file mode 100644 index 0000000000000000000000000000000000000000..77a2d020362b75743cbe96fefa87d69cabd26457 --- /dev/null +++ b/src/hooks/urlhook.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef URL_HOOK_H +#define URL_HOOK_H + +#include <string> +#include <stdlib.h> + +#define RUN_COMMAND(command) system(command); + +class UrlHook { + + public: + /** + * Constructor + */ + UrlHook (); + + /** + * Destructor + */ + ~UrlHook (); + + void addAction (std::string, std::string); + + private: +}; + +#endif // URL_HOOK_H diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 9315572eb80ae12be08028b92ec5f6108bdd4a83..b381c6181ce6a942173130251dde4741afc856c7 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -375,9 +375,12 @@ ManagerImpl::onHoldCall(const CallID& id) { AccountID accountid; bool returnValue; + CallID call_id; stopTone(true); + call_id = id; + /* Direct IP to IP call */ if (getConfigFromCall (id) == Call::IPtoIP) { returnValue = SIPVoIPLink::instance (AccountNULL)-> onhold (id); @@ -396,7 +399,7 @@ ManagerImpl::onHoldCall(const CallID& id) removeWaitingCall(id); switchCall(""); - if (_dbus) _dbus->getCallManager()->callStateChanged(id, "HOLD"); + if (_dbus) _dbus->getCallManager()->callStateChanged(call_id, "HOLD"); return returnValue; } @@ -409,12 +412,15 @@ ManagerImpl::offHoldCall(const CallID& id) AccountID accountid; bool returnValue, rec; std::string codecName; + CallID call_id; stopTone(false); + call_id = id; //Place current call on hold if it isn't if (hasCurrentCall()) { + _debug ("Put the current call (ID=%s) on hold\n", getCurrentCallId().c_str()); onHoldCall(getCurrentCallId()); } @@ -438,16 +444,16 @@ ManagerImpl::offHoldCall(const CallID& id) if (_dbus){ if (rec) - _dbus->getCallManager()->callStateChanged(id, "UNHOLD_RECORD"); + _dbus->getCallManager()->callStateChanged(call_id, "UNHOLD_RECORD"); else - _dbus->getCallManager()->callStateChanged(id, "UNHOLD_CURRENT"); + _dbus->getCallManager()->callStateChanged(call_id, "UNHOLD_CURRENT"); } switchCall(id); - // codecName = getCurrentCodecName(id); + codecName = getCurrentCodecName(id); // _debug("ManagerImpl::hangupCall(): broadcast codec name %s \n",codecName.c_str()); - // if (_dbus) _dbus->getCallManager()->currentSelectedCodec(id,codecName.c_str()); + if (_dbus) _dbus->getCallManager()->currentSelectedCodec(id,codecName.c_str()); return returnValue; } @@ -739,7 +745,9 @@ ManagerImpl::incomingCall(Call* call, const AccountID& accountId) */ /* Broadcast a signal over DBus */ - _dbus->getCallManager()->incomingCall(accountId, call->getCallId(), from); + if (_dbus) _dbus->getCallManager()->incomingCall(accountId, call->getCallId(), from); + + //if (_dbus) _dbus->getCallManager()->callStateChanged(call->getCallId(), "INCOMING"); // Reduce volume of the other pulseaudio-connected audio applications if( _audiodriver->getLayerType() == PULSEAUDIO && getConfigInt( PREFERENCES , CONFIG_PA_VOLUME_CTRL ) ) { @@ -787,7 +795,6 @@ ManagerImpl::peerRingingCall(const CallID& id) void ManagerImpl::peerHungupCall(const CallID& id) { - _debug("ManagerImpl::peerHungupCall():this function is called when peer hangup \n"); PulseLayer *pulselayer; AccountID accountid; bool returnValue; @@ -977,15 +984,12 @@ ManagerImpl::ringtone() { //TODO Comment this because it makes the daemon crashes since the main thread //synchronizes the ringtone thread. - _debug("RINGING!!! 1\n"); ringchoice = getConfigString(AUDIO, RING_CHOICE); //if there is no / inside the path if ( ringchoice.find(DIR_SEPARATOR_CH) == std::string::npos ) { // check inside global share directory ringchoice = std::string(PROGSHAREDIR) + DIR_SEPARATOR_STR + RINGDIR + DIR_SEPARATOR_STR + ringchoice; - - _debug("RINGING!!! 2\n"); } audiolayer = getAudioDriver(); @@ -993,7 +997,6 @@ ManagerImpl::ringtone() if (audiolayer == 0) return; - _debug("RINGING!!! 3\n"); samplerate = audiolayer->getSampleRate(); codecForTone = _codecDescriptorMap.getFirstCodecAvailable(); @@ -1004,7 +1007,6 @@ ManagerImpl::ringtone() if (loadFile) { - _debug("RINGING!!! 5\n"); _toneMutex.enterMutex(); _audiofile.start(); _toneMutex.leaveMutex(); @@ -1014,18 +1016,15 @@ ManagerImpl::ringtone() } else{ audiolayer->startStream(); - _debug("RINGING!!! 6\n"); } } else { ringback(); - _debug("RINGING!!! 7\n"); } } else { ringback(); - _debug("RINGING!!! 8\n"); } } @@ -1206,6 +1205,11 @@ ManagerImpl::initConfigFile ( bool load_user_value ) fill_config_int (ADDRESSBOOK_DISPLAY_PHONE_HOME, NO_STR); fill_config_int (ADDRESSBOOK_DISPLAY_PHONE_MOBILE, NO_STR); + section = HOOKS; + fill_config_str (URLHOOK_SIP_FIELD, HOOK_DEFAULT_SIP_FIELD); + fill_config_str (URLHOOK_COMMAND, HOOK_DEFAULT_URL_COMMAND); + fill_config_str (URLHOOK_SIP_ENABLED, NO_STR); + // Loads config from ~/.sflphone/sflphonedrc or so.. if (createSettingsPath() == 1 && load_user_value) { _exist = _config.populateFromFile(_path); @@ -2527,7 +2531,7 @@ void ManagerImpl::registerCurSIPAccounts(VoIPLink *link) current = iter->second; if (current) { - if ( current->isEnabled() && current->getType() == "sip") { + if (current->isEnabled() && current->getType() == "sip") { //current->setVoIPLink(link); current->registerVoIPLink(); } @@ -2563,6 +2567,31 @@ void ManagerImpl::setAddressbookSettings (const std::map<std::string, int32_t>& saveConfig (); } + +std::map<std::string, std::string> ManagerImpl::getHookSettings () { + + std::map<std::string, std::string> settings; + + settings.insert (std::pair<std::string, std::string> ("URLHOOK_SIP_FIELD", getConfigString (HOOKS, URLHOOK_SIP_FIELD)) ); + settings.insert (std::pair<std::string, std::string> ("URLHOOK_COMMAND", getConfigString (HOOKS, URLHOOK_COMMAND)) ); + settings.insert (std::pair<std::string, std::string> ("URLHOOK_SIP_ENABLED", getConfigString (HOOKS, URLHOOK_SIP_ENABLED)) ); + + return settings; +} + +void ManagerImpl::setHookSettings (const std::map<std::string, std::string>& settings){ + + setConfig(HOOKS, URLHOOK_SIP_FIELD, (*settings.find("URLHOOK_SIP_FIELD")).second); + setConfig(HOOKS, URLHOOK_COMMAND, (*settings.find("URLHOOK_COMMAND")).second); + setConfig(HOOKS, URLHOOK_SIP_ENABLED, (*settings.find("URLHOOK_SIP_ENABLED")).second); + + // Write it to the configuration file + saveConfig (); +} + + + + void ManagerImpl::check_call_configuration (const CallID& id, const std::string &to, Call::CallConfiguration *callConfig) { std::string pattern; Call::CallConfiguration config; diff --git a/src/managerimpl.h b/src/managerimpl.h index 6d6f8b5ef2c4261542b33db643e61f0ddbc23ac4..2e4aed50d9023695ebedd627414546a0d567e0c7 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -562,6 +562,17 @@ class ManagerImpl { * Addressbook configuration */ void setAddressbookSettings (const std::map<std::string, int32_t>& settings); + + /** + * Hook configuration + */ + std::map<std::string, std::string> getHookSettings (void); + + /** + * Hook configuration + */ + void setHookSettings (const std::map<std::string, std::string>& settings); + /** * Get the audio manager diff --git a/src/sdp.cpp b/src/sdp.cpp index 63a5b69d58da240126aa7ebe7bc8b140e0660fcd..2c623f8d46e2f9763731c0dc6f07c93ad1927e34 100644 --- a/src/sdp.cpp +++ b/src/sdp.cpp @@ -379,7 +379,6 @@ void Sdp::set_local_media_capabilities () { } } _local_media_cap.push_back (audio); - _debug ("%s\n", audio->to_string ().c_str()); } void Sdp::attribute_port_to_all_media (int port) { @@ -408,7 +407,6 @@ void Sdp::fetch_remote_ip_from_sdp (pjmedia_sdp_session *r_sdp) { std::string remote_ip; remote_ip = r_sdp->conn->addr.ptr; - _debug("************************************************** Remote Audio IP: %s\n", remote_ip.c_str()); this->set_remote_ip(remote_ip); } diff --git a/src/sipaccount.cpp b/src/sipaccount.cpp index fc77c0450de4814c82d05b29aea2d5072e82b425..0dceb51243d46872583ee509a55f79bcdc6b5647 100644 --- a/src/sipaccount.cpp +++ b/src/sipaccount.cpp @@ -69,14 +69,14 @@ int SIPAccount::registerVoIPLink() int SIPAccount::unregisterVoIPLink() { - _debug("unregister account %s\n" , getAccountID().c_str()); - - _regc = NULL; - - if(_link->sendUnregister( _accountID )) - return true; - else - return false; + _debug("unregister account %s\n" , getAccountID().c_str()); + + if(_link->sendUnregister( _accountID )){ + setRegistrationInfo (NULL); + return true; + } + else + return false; } diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index 4053df3cc63f12e1942380599078762cb8bfa958..12e014016fd358f8b918f578e002b31cd833b11a 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -49,6 +49,10 @@ int getModId(); * */ bool setCallAudioLocal(SIPCall* call, std::string localIP, bool stun, std::string server); +void handle_incoming_options (pjsip_rx_data *rxdata); + +std::string fetch_header_value (pjsip_msg *msg, std::string field); + /* * The global pool factory */ @@ -75,6 +79,11 @@ pjsip_module _mod_ua; pj_thread_t *thread; pj_thread_desc desc; +/* + * Url hook instance + */ +UrlHook *urlhook; + /** * Get the number of voicemail waiting in a SIP message */ @@ -101,7 +110,7 @@ void call_on_state_changed( pjsip_inv_session *inv, pjsip_event *e); void call_on_media_update( pjsip_inv_session *inv UNUSED, pj_status_t status UNUSED); /* - * Called when the invote usage module has created a new dialog and invite + * Called when the invite usage module has created a new dialog and invite * because of forked outgoing request. * * @param inv A pointer on a pjsip_inv_session structure @@ -169,6 +178,8 @@ SIPVoIPLink* SIPVoIPLink::_instance = NULL; // to get random number for RANDOM_PORT srand (time(NULL)); + urlhook = new UrlHook (); + /* Start pjsip initialization step */ init(); } @@ -258,6 +269,7 @@ SIPVoIPLink::terminateOneCall(const CallID& id) } void get_remote_sdp_from_offer( pjsip_rx_data *rdata, pjmedia_sdp_session** r_sdp ){ + pjmedia_sdp_session *sdp; pjsip_msg *msg; pjsip_msg_body *body; @@ -268,9 +280,13 @@ void get_remote_sdp_from_offer( pjsip_rx_data *rdata, pjmedia_sdp_session** r_sd body = msg->body; // Parse the remote request to get the sdp session - pjmedia_sdp_parse( rdata->tp_info.pool, (char*)body->data, body->len, &sdp ); + if (body) { + pjmedia_sdp_parse( rdata->tp_info.pool, (char*)body->data, body->len, &sdp ); + *r_sdp = sdp; + } - *r_sdp = sdp; + else + *r_sdp = NULL; } void @@ -307,14 +323,12 @@ int SIPVoIPLink::sendRegister( AccountID id ) /* Get the client registration information for this particular account */ regc = account->getRegistrationInfo(); - /* If the registration already exists, delete it */ - if(regc) { - + /* TODO If the registration already exists, delete it */ + /*if(regc) { status = pjsip_regc_destroy(regc); regc = NULL; PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 ); - } - + }*/ account->setRegister(true); @@ -324,7 +338,6 @@ int SIPVoIPLink::sendRegister( AccountID id ) /* Update the state of the voip link */ account->setRegistrationState(Trying); - if (!validStunServer) { account->setRegistrationState(ErrorExistStun); account->setRegister(false); @@ -380,7 +393,6 @@ int SIPVoIPLink::sendRegister( AccountID id ) return false; } - status = pjsip_regc_send(regc, tdata); if (status != PJ_SUCCESS) { _debug("UserAgent: Unable to send regc request.\n"); @@ -396,7 +408,7 @@ int SIPVoIPLink::sendRegister( AccountID id ) } int -SIPVoIPLink::sendUnregister( AccountID id ) +SIPVoIPLink::sendUnregister (AccountID id) { pj_status_t status = 0; pjsip_tx_data *tdata = NULL; @@ -428,7 +440,7 @@ SIPVoIPLink::sendUnregister( AccountID id ) return false; } - account->setRegistrationInfo(regc); + //account->setRegistrationInfo(regc); account->setRegister(false); return true; @@ -714,6 +726,7 @@ SIPVoIPLink::offhold(const CallID& id) bool SIPVoIPLink::transfer(const CallID& id, const std::string& to) { + SIPCall *call; std::string tmp_to; pjsip_evsub *sub; @@ -724,7 +737,6 @@ SIPVoIPLink::transfer(const CallID& id, const std::string& to) AccountID account_id; Account* account; - call = getSIPCall(id); call->stopRecording(); account_id = Manager::instance().getAccountFromCall(id); @@ -736,8 +748,14 @@ SIPVoIPLink::transfer(const CallID& id, const std::string& to) } tmp_to = SIPToHeader(to); - if (tmp_to.find("@") == std::string::npos) { - tmp_to = tmp_to + "@" + account->getHostname(); + if (account) { + if (tmp_to.find("@") == std::string::npos) { + tmp_to = tmp_to + "@" + account->getHostname(); + } + } + + else { + } _debug("In transfer, tmp_to is %s\n", tmp_to.data()); @@ -759,7 +777,6 @@ SIPVoIPLink::transfer(const CallID& id, const std::string& to) * because after this function, we can not find the cooresponding * voiplink from the call any more. But the voiplink is useful! */ - AccountID accId = Manager::instance().getAccountFromCall(call->getCallId()); pjsip_evsub_set_mod_data(sub, getModId(), this); /* @@ -970,7 +987,10 @@ SIPVoIPLink::SIPStartCall(SIPCall* call, const std::string& subject UNUSED) &to, NULL, &dialog); - PJ_ASSERT_RETURN(status == PJ_SUCCESS, false); + if (status != PJ_SUCCESS){ + _debug ("UAC creation failed\n"); + return false; + } // Create the invite session for this call status = pjsip_inv_create_uac(dialog, call->getLocalSDP()->get_local_sdp_session(), 0, &inv); @@ -1376,7 +1396,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam _debug("UserAgent: VOIP callbacks initialized\n"); // Add endpoint capabilities (INFO, OPTIONS, etc) for this UA - pj_str_t allowed[] = { {(char*)"INFO", 4}, {(char*)"REGISTER", 8} }; // //{"INVITE", 6}, {"ACK",3}, {"BYE",3}, {"CANCEL",6}, {"OPTIONS", 7}, + pj_str_t allowed[] = { {(char*)"INFO", 4}, {(char*)"REGISTER", 8}, {(char*)"OPTIONS", 7} }; // //{"INVITE", 6}, {"ACK",3}, {"BYE",3}, {"CANCEL",6} accepted = pj_str((char*)"application/sdp"); // Register supported methods @@ -1619,8 +1639,6 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam SIPVoIPLink *link; pjsip_rx_data *rdata; - _debug (" ***************************** NEW CALL STATE %i **************************\n", inv->state); - /* Retrieve the call information */ call = reinterpret_cast<SIPCall*> (inv->mod_data[_mod_ua.id]); if(!call) @@ -1688,16 +1706,14 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam } else { - // The call is ringing - if (inv->state == PJSIP_INV_STATE_EARLY){ - _debug ("*************************** PJSIP_INV_STATE_EARLY - PEER RINGING ***********************************\n"); + // The call is ringing - We need to handle this case only on outgoing call + if (inv->state == PJSIP_INV_STATE_EARLY && e->body.tsx_state.tsx->role == PJSIP_ROLE_UAC){ call->setConnectionState(Call::Ringing); Manager::instance().peerRingingCall(call->getCallId()); } // We receive a ACK - The connection is established else if( inv->state == PJSIP_INV_STATE_CONFIRMED ){ - _debug ("*************************** PJSIP_INV_STATE_CONFIRMED ***********************************\n"); /* If the call is a direct IP-to-IP call */ if (call->getCallConfiguration () == Call::IPtoIP) { @@ -1713,7 +1729,6 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam } else if( inv->state == PJSIP_INV_STATE_DISCONNECTED ){ - _debug ("*************************** PJSIP_INV_STATE_DISCONNECTED %i***********************************\n", inv->cause); switch( inv->cause ) { /* The call terminates normally - BYE / CANCEL */ @@ -1794,11 +1809,11 @@ void call_on_tsx_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_e */ _debug("UserAgent: The error is: %d\n", param->code); switch(param->code) { - case 408: case 606: account->setRegistrationState(ErrorConfStun); break; case 503: + case 408: account->setRegistrationState(ErrorHost); break; case 401: @@ -1912,6 +1927,12 @@ void call_on_tsx_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_e return true; } + // Handle an OPTIONS message + if (rdata->msg_info.msg->line.req.method.id == PJSIP_OPTIONS_METHOD) { + handle_incoming_options (rdata); + return true; + } + // Respond statelessly any non-INVITE requests with 500 if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) { if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) { @@ -1931,6 +1952,22 @@ void call_on_tsx_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_e return true; } + /******************************************* URL HOOK *********************************************/ + + if (Manager::instance().getConfigString (HOOKS, URLHOOK_SIP_ENABLED) == "1") { + + std::string header_value; + + header_value = fetch_header_value (rdata->msg_info.msg, Manager::instance().getConfigString (HOOKS, URLHOOK_SIP_FIELD)); + + if (header_value!=""){ + urlhook->addAction (header_value, + Manager::instance().getConfigString (HOOKS, URLHOOK_COMMAND)); + } + } + + /************************************************************************************************/ + // Generate a new call ID for the incoming call! id = Manager::instance().getNewCallID(); call = new SIPCall(id, Call::Incoming, _pool); @@ -2429,8 +2466,6 @@ void call_on_tsx_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_e void on_rx_offer( pjsip_inv_session *inv, const pjmedia_sdp_session *offer ){ - _debug ( "********************************* REINVITE RECEIVED *******************************\n" ); - #ifdef CAN_REINVITE _debug ("reinvite SIP\n"); @@ -2454,6 +2489,50 @@ void call_on_tsx_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_e } + void handle_incoming_options (pjsip_rx_data *rdata) { + + pjsip_tx_data *tdata; + pjsip_response_addr res_addr; + const pjsip_hdr *cap_hdr; + pj_status_t status; + + /* Create basic response. */ + status = pjsip_endpt_create_response(_endpt, rdata, PJSIP_SC_OK, NULL, &tdata); + if (status != PJ_SUCCESS) { + return; + } + + /* Add Allow header */ + cap_hdr = pjsip_endpt_get_capability(_endpt, PJSIP_H_ALLOW, NULL); + if (cap_hdr) { + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, cap_hdr)); + } + + /* Add Accept header */ + cap_hdr = pjsip_endpt_get_capability(_endpt, PJSIP_H_ACCEPT, NULL); + if (cap_hdr) { + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, cap_hdr)); + } + + /* Add Supported header */ + cap_hdr = pjsip_endpt_get_capability(_endpt, PJSIP_H_SUPPORTED, NULL); + if (cap_hdr) { + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, cap_hdr)); + } + + /* Add Allow-Events header from the evsub module */ + cap_hdr = pjsip_evsub_get_allow_events_hdr(NULL); + if (cap_hdr) { + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, cap_hdr)); + } + + /* Send response statelessly */ + pjsip_get_response_addr(tdata->pool, rdata, &res_addr); + status = pjsip_endpt_send_response(_endpt, &res_addr, tdata, NULL, NULL); + if (status != PJ_SUCCESS) + pjsip_tx_data_dec_ref(tdata); + } + /*****************************************************************************************************************/ @@ -2480,4 +2559,31 @@ void call_on_tsx_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_e return true; } + std::string fetch_header_value (pjsip_msg *msg, std::string field) { + + pj_str_t name; + pjsip_generic_string_hdr * hdr; + std::string value, url; + size_t pos; + + std::cout << "fetch header value" << std::endl; + + /* Convert the field name into pjsip type */ + name = pj_str ((char*)field.c_str()); + + /* Get the header value and convert into string*/ + hdr = (pjsip_generic_string_hdr*) pjsip_msg_find_hdr_by_name (msg, &name, NULL); + + if (!hdr) + return ""; + + value = hdr->hvalue.ptr; + if ( (pos=value.find ("\n")) == std::string::npos) { + return ""; + } + + url = value.substr (0, pos); + return url; + } + diff --git a/src/sipvoiplink.h b/src/sipvoiplink.h index 92212c29353f982c147eccdf49356f0f6ce09de6..51bd9a01378b6a6f3dcf1ce90a664736927aba6d 100644 --- a/src/sipvoiplink.h +++ b/src/sipvoiplink.h @@ -23,6 +23,7 @@ #define SIPVOIPLINK_H #include "voiplink.h" +#include "hooks/urlhook.h" ////////////////////////////// /* PJSIP imports */ diff --git a/src/user_cfg.h b/src/user_cfg.h index 62bb5579e7676c4efac340749324a751bae83de1..48b78965d4ca9cf570f479e37f01b26a11270df7 100644 --- a/src/user_cfg.h +++ b/src/user_cfg.h @@ -78,8 +78,13 @@ #define ADDRESSBOOK_DISPLAY_PHONE_HOME "Addressbook.phone_home" #define ADDRESSBOOK_DISPLAY_PHONE_MOBILE "Addressbook.phone_mobile" +#define HOOKS "Hooks" /** Hooks section */ +#define URLHOOK_SIP_FIELD "Hooks.url_sip_field" +#define URLHOOK_COMMAND "Hooks.url_command" +#define URLHOOK_SIP_ENABLED "Hooks.sip_enabled" + #define EMPTY_FIELD "" /** Default value for empty field */ -#define DFT_STUN_SERVER "stun.fwdnet.net:3478" /** Default STUN server address */ +#define DFT_STUN_SERVER "stun.ekiga.net" /** Default STUN server address */ #define YES_STR "1" /** Default YES value */ #define NO_STR "0" /** Default NO value */ #define DFT_PULSE_LENGTH_STR "250" /** Default DTMF lenght */ diff --git a/test/hooksTest.h b/test/hooksTest.h new file mode 100644 index 0000000000000000000000000000000000000000..a08e7e3ecd19a5e6695f0da45c8c7a3d72f19cf3 --- /dev/null +++ b/test/hooksTest.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +// Cppunit import +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCaller.h> +#include <cppunit/TestCase.h> +#include <cppunit/TestSuite.h> + +#include <assert.h> + +/* + * @file hooksTest.cpp + * @brief Regroups unitary tests related to the hooks. + */ + +#ifndef _HOOKS_TEST_ +#define _HOOKS_TEST_ + +class HooksTest : public CppUnit::TestCase { + + /** + * Use cppunit library macros to add unit test the factory + */ + CPPUNIT_TEST_SUITE (HooksTest); + CPPUNIT_TEST (); + CPPUNIT_TEST_SUITE_END(); + + public: + HooksTest() : CppUnit::TestCase("Hooks implementation Tests") {} + + /* + * Code factoring - Common resources can be initialized here. + * This method is called by unitcpp before each test + */ + void setUp(); + + /* + * Code factoring - Common resources can be released here. + * This method is called by unitcpp after each test + */ + inline void tearDown (); + + void testUnloadPlugins (); + + private: +}; + +/* Register our test module */ +CPPUNIT_TEST_SUITE_REGISTRATION (HooksTest); + +# diff --git a/tools/build-package.sh b/tools/build-package.sh index c2d4d5f85bab8e25b70fddf6a43dcd2cb23bf365..ec95e8e38a9d3fb53de97fa94b1d208c8b260b54 100755 --- a/tools/build-package.sh +++ b/tools/build-package.sh @@ -54,7 +54,7 @@ git checkout origin/release -b release # Get system parameters arch_flag=`getconf -a|grep LONG_BIT | sed -e 's/LONG_BIT\s*//'` os_version=`lsb_release -d -s -c | sed -e '1d'` -ver=0.9.3 +ver=0.9.4 if [ $platform == "ubuntu" ];then # Generate the changelog, according to the distribution and the git commit messages