Incorporate ant-phone 0.1.13

This commit is contained in:
Roland Stigge 2007-11-24 14:45:25 +01:00
parent 4000812707
commit 639a23e720
79 changed files with 17718 additions and 0 deletions

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
ABOUT-NLS
INSTALL
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.guess
config.h
config.h.in
config.log
config.rpath
config.status
config.sub
configure
depcomp
ant-phone-*.tar.gz
install-sh
intl
m4
missing
mkinstalldirs
stamp-h1
ylwrap

11
AUTHORS Normal file
View File

@ -0,0 +1,11 @@
Roland Stigge <stigge@antcom.de> (lead developer / maintainer)
Joerg Mayer <jmayer@loplof.de> (automake/autoconf Support)
Lars Volkhardt <Lars.Volkhardt@uni-konstanz.de> (save callerid list to file)
Mario Andrés Pagella <mapagella@fitzroy-is.com.ar> (project logo)
Translators:
FACORAT Fabrice <f.faber-pro@ifrance.com> (French)
Roel Koelewijn <rl.koelewijn@home.nl> (Dutch)

340
COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

143
ChangeLog Normal file
View File

@ -0,0 +1,143 @@
ant-phone 0.1.13, 2007-04-29, Roland Stigge <stigge@antcom.de>
* Included Italian translation
ant-phone 0.1.12, 2006-04-18, Roland Stigge <stigge@antcom.de>
* Updated Swedish translation
ant-phone 0.1.11, 2005-11-29, Roland Stigge <stigge@antcom.de>
* Added Swedish, Turkish and Vietnamese translations
ant-phone 0.1.10, 2004-01-09, Roland Stigge <stigge@antcom.de>
* src/session.c: Added debug messages to gtk_handle_isdn_input
* Updated po/fr.po
ant-phone 0.1.9, 2004-01-09, Roland Stigge <stigge@antcom.de>
* README: Added reference to mailing list and archives
* Updated po/fr.po
ant-phone 0.1.8, 2003-11-18, Roland Stigge <stigge@antcom.de>
* src/isdn.h: Fixed ISDN_CONFIG_FILENAME to be /etc/isdn/isdn.conf
* src/callerid.c: Fixed segfault in cid_calls_merge()
ant-phone 0.1.7, 2003-10-31, Roland Stigge <stigge@antcom.de>
* Updated po/nl.po
ant-phone 0.1.6, 2003-10-01, Roland Stigge <stigge@antcom.de>
* Fixed yyloc compile warning, updating flex and bison source for
options and callerid (solves parsers location issue)
* Applied SuSE (Opteron, ...) porting patches, thanks to
Philipp Thomas <pthomas@suse.de>:
ant-phone-codecleanup.diff
ant-phone-gettext_version.diff
ant-phone-isdn_log_name.diff
ant-phone-makefile.diff
* Adjusted to automake-1.7
* Added lexer/parser for isdnformat(5) to get name of calls file
from i4l config file
* Obsoleted optionslexer in favour of isdnparser (nearly same format)
to conform rc file to isdnformat(5)
* Added ro.po translation file (Romanian)
ant-phone 0.1.5, 2003-07-30, Roland Stigge <stigge@antcom.de>
* Fixed bad codeset (UTF-8) in localized command line output
* Updated po/fr.po
* Fixed bug in resampling code for playback
* Added xpm icons in src/: 16x16, 32x32, 48x48, 64x64
* Added auto detection between /var/lib/isdn/calls and
/var/log/isdn/calls as input file for callerid history
ant-phone 0.1.4, 2003-07-06, Roland Stigge <stigge@antcom.de>
* Fixed parse error in src/callerid.c (line 422 in version 0.1.3)
* Updated po/nl.po
* Coded variable size for buttons (suitable for i18n) in src/gtk.c
ant-phone 0.1.3, 2003-07-06, Roland Stigge <stigge@antcom.de>
* Fixed: recording of parts of one session to different files
(now dependent on session->vcon_time)
* Added playback / copy / deletion of recorded sessions to context
menu of CallerID rows
* Added po/fr.po, thanks to FACORAT Fabrice <f.faber@ifrance.com>
* Fixed gettext_noop warning in globals.h (commented out #define)
* Fixed default notebook page in settings to first one
* Fixed focus on dial combo box after keypad (digit) input
* Added po/nl.po, thanks to roel koelewijn <rl.koelewijn@home.nl>
* Changed gettext marks for menus (with "_" even for
gtk_item_factory_get_item() requests) to prevent ambiguousness
* Settings notebook: leave default page 1 instead of forcing focus
for msn_entry
ant-phone 0.1.2, 2003-06-29, Roland Stigge <stigge@antcom.de>
* Created hierarchy in source package structure (doc/, src/, ...)
* Port to GTK+ 2.x
* New logo, added to "About" window
* Added internationalization via GNU gettext; included po/de.po
ant-phone 0.1.1, 2003-05-28, Roland Stigge <stigge@antcom.de>
* Code cleanup
* Use gtk_window_present() for popup on GTK+ >= 2.0
* Let keypad Enter act as Enter in dial combo box
* Added %s on substitution in execution string (= caller's number),
fixes problem that %n actually substitutes to own msn
* configure.ac: Added complaints on missing library sndfile
* Added copying permission statement to all source files
to conform to GNU advice on GPL usage
ant-phone 0.1.0, 2003-04-27, Roland Stigge
* Added recording (depends on libsndfile)
* Added option to popup on incoming call
* Added configurable preset buttons
* Added isdnlog data import
* Added context menu to CallerID list
* Added delete function to CallerID list
* Added tracking for unanswered calls in CallerID list and in window
title
ant-phone 0.0.8, 2002-12-09, Roland Stigge
* fixed "local bind: No such file or directory" and exit on startup
ant-phone 0.0.7, 2002-12-06, Roland Stigge
* fixed include mistake in isdn.c
* added caller id saved history patch by
Lars Volkhardt <Lars.Volkhardt@uni-konstanz.de>
* added lexer/parser for caller id saved history file
* ant-phone now doesn't try to open sound device(s) at startup
when in audio release mode
* made number of caller id entries configurable
* added option to start a command when incoming call comes
* added command line option to let an already running ant make a call
ant-phone 0.0.6, 2002-11-22, Roland Stigge
* made release audio mode default
* release audio also in settings
* added control pad (for dialing / generating touchtones)
* added touchtone generator
* added mute function
ant-phone 0.0.5, 2002-11-13, Roland Stigge
* autoconf/automake support by Joerg Mayer <jmayer@loplof.de>
* added saved options / history files
* added "release audio devices on idle"
ant-phone 0.0.4, 2002-11-03, Roland Stigge
* fixed gcc-3.2 warnings (session.c, sound.c),
reported by Joerg Mayer <jmayer@loplof.de>
* fixed delay problem with ALSA
ant-phone 0.0.3, 2002-11-01, Roland Stigge
* fixed "Warning: Got audio input in ready mode."
* minor bug fixes
* added/improved GUI elements
* added installer (make install target)
* added man page
* added line level checker
ant-phone 0.0.2, 2002-10-16, Roland Stigge
* renamed package to prevent "confusion" with ANT (Another Neat Tool)
* added caller id support
* added vanity number support
* added playing sound on incoming and outgoing calls
* bug fixes (hanging sound init)
ant 0.0.1, 2002-09-23, Roland Stigge
* first release of ANT (ANT is Not a Telephone)
* basic functionality

7
Makefile.am Normal file
View File

@ -0,0 +1,7 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = intl doc src po
EXTRA_DIST = config.rpath autogen.sh ABOUT-NLS
AUTOMAKE_OPTIONS = dist-bzip2

0
NEWS Normal file
View File

74
TODO Normal file
View File

@ -0,0 +1,74 @@
Bugs:
=====
* Recording chopped up (only recorded file)
* Incoming delay
* Kernel cpu consumption in conversation mode. This is a kernel-internal
problem. While reading blocks from kernel OSS devices and ttyI, select(s)
seems to consume lot's of cpu time in kernel space while NOT BLOCKING!
-> not a big problem for now, just less idle tasks ;)
-> The problem doesn't seem to appear with ALSA
Feature requests:
=================
* Real time support
* client/server architecture (ttyI network forward) (Sven Geggus <sven@gegg.us>, Arne Börs <Arne.Boers@gmx.de>, martin@stigge.org)
* Makeln (Joerg Brueggemann <jb@neviges.net>)
* database connection (caller id, times of incoming / outgoing, ...)
Christoph Schütz <ch.schuetz@addcom.de>:
* echo compensation
* configurable different ringtones (for different callers)
Steffen Barszus <st_barszus@gmx.de>:
* kde-kicker integration (drag number, pop up menu: number input)
Pinto Joel <joelp@india.hp.com>:
* recording / scripting
Roel Koelewijn <rl.koelewijn@home.nl>:
* KDE address book integration
* TAPI telephone (dialling) support
* connection to external DB (Phonebook CDs)
Martin Stigge <martin@stigge.org>:
* sorting callerid list
* playback soundfiles in converation mode
arnd.feldmueller@t-online.de:
* answering machine
* DB, SQL, CSV input/output
Arthur J. Schotgerrits <arthur@rev-img.nl>:
* answering machine
Matthias Fenner <informix@web.de>:
* command line interface
Daniel Nöthen <bipak@gmx.net>:
* mixer support (muting)
* (configurable?) auto set input to mic (reset on exit)
* separate configuration of logged / ringing msns
Philipp Thomas <pthomas@suse.de>:
* CAPI support, native ALSA support (both in Linux 2.6) (needed for SuSE 9.1 prepared for 02/2004)
wolfgang@rohdewald.de:
* "execute on recorded message" option
* aRTs support
* IP telephony support
Feature ideas: (tell me to move some of them to "feature requests")
==============
* graphical sound visualization
* compensate sample drift (difference between isdn and oss)
* BSD (and possibly other) UNIX support
* H.323 client functionality
* encryption support
* adaptive (pre-)amp / echo compensation
* answering machine
* website enhancements / maintenance
* Remove remaining deprecated GTK+ functions, adjust to new API
* Logarithmical line level meter
* improve calls file finding by parsing /etc/isdn/callerid.conf

8
autogen.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
#gettextize --force --copy --intl --no-changelog
autopoint --force
aclocal
autoheader
automake --copy --add-missing --force-missing --gnu
autoconf

77
configure.ac Normal file
View File

@ -0,0 +1,77 @@
# Process this file with autoconf to produce a configure script.
AC_INIT(ant-phone)
AM_INIT_AUTOMAKE(ant-phone, "0.1.13", ant-phone-devel@nongnu.org)
AC_PREREQ(2.53)
AC_CONFIG_SRCDIR([config.h.in])
AM_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AM_PROG_LEX
if test "$LEX" != flex; then
LEX="$SHELL $missing_dir/missing flex"
AC_SUBST(LEX_OUTPUT_ROOT, lex.yy)
AC_SUBST(LEXLIB, '')
fi
AC_PROG_YACC
# Checks for libraries.
AC_CHECK_LIB([m], [floor])
AC_CHECK_LIB([sndfile], [sf_open],, AC_MSG_ERROR(You need the libsndfile headers to build this package))
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h limits.h math.h pwd.h stddef.h stdlib.h string.h sys/ioctl.h sys/stat.h sys/time.h sys/types.h termios.h unistd.h sndfile.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_HEADER_TIME
# Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MALLOC
AC_TYPE_SIGNAL
AC_FUNC_STRFTIME
AC_CHECK_FUNCS([floor select strdup strstr strtol mkdir strcasecmp])
# GTK+ 2.0:
PKG_CHECK_MODULES(DEPS, gtk+-2.0)
AC_SUBST(DEPS_CFLAGS)
AC_SUBST(DEPS_LIBS)
#
# If we're running gcc, add '-Wall -W' to CFLAGS, and add
# '-D_U_="__attribute__((unused))"' as well, so we can use _U_ to
# flag unused function arguments and not get warnings about them.
#
# Otherwise, add '-D_U_=""', so that _U_ used to flag an unused function
# argument will compile with non-GCC compilers.
#
AC_MSG_CHECKING(to see if we can add '-Wall -W' to CFLAGS)
if test x$GCC != x ; then
CFLAGS="$CFLAGS -D_U_=\"__attribute__((unused))\" -Wall -W -D_GNU_SOURCE -O3"
AC_MSG_RESULT(yes)
else
CFLAGS="-D_U_=\"\" $CFLAGS"
AC_MSG_RESULT(no)
fi
# GNU gettext
AM_GNU_GETTEXT
AM_GNU_GETTEXT_VERSION(0.16.1)
# directory containing configuration support files
# defaults to package root
#AC_CONFIG_AUX_DIR
AC_CONFIG_FILES([Makefile
intl/Makefile
po/Makefile.in
doc/Makefile
src/Makefile])
AC_OUTPUT

7
doc/Makefile.am Normal file
View File

@ -0,0 +1,7 @@
## Process this file with automake to produce Makefile.in
man_MANS = ant-phone.1
EXTRA_DIST = \
$(man_MANS)

60
doc/ant-phone.1 Normal file
View File

@ -0,0 +1,60 @@
.TH ant-phone 1 "27 April 2003" "Version 0.1.0" "ANT Manual Pages"
.SH NAME
ant-phone \- an interactive ISDN telephone application
.SH SYNOPSIS
.B ant-phone
.RI [ options ]
.SH DESCRIPTION
ant-phone is part of ANT (ANT is Not a Telephone). It let's you make and receive telephone calls and talk via sound devices. It uses ISDN4Linux ttyI devices.
.SH OPTIONS
ant-phone accepts the following options:
.TP
.B \-h, \-\-help
Show summary of options
.TP
.B \-v, \-\-version
Print version information
.TP
.B \-r, \-\-cleanup
Remove stale socket file left by accident by a previous run of ANT. You only need this option if ANT says: "local bind: Address already in use"
.TP
.BI "\-d, \-\-debug" [ = debuglevel]
Print additional runtime debugging data to stdout, debuglevel = 1..2
.TP
.BI "\-i, \-\-soundin=" device
OSS compatible device for input (recording),
default: /dev/dsp
.TP
.BI "\-o, \-\-soundout=" device
OSS compatible device for output (playback),
default: /dev/dsp
.TP
.BI "\-m, \-\-msn=" msn
identifying MSN (for outgoing calls), 0 for master MSN of this
termination/port,
default: 0
.TP
.BI "\-l, \-\-msns=" msns
MSNs to listen on, semicolon-separated list or '*',
default: *
.TP
.BI "\-c, \-\-call=" number
Make a running instance of ANT make a call to the specified number,
useful for calling from an external address book application
.SH NOTES
If the used sound devices (arguments of \-\-soundin and \-\-soundout)
are equal, a full duplex sound device is needed.
.SH FILES
.TP
.I ~/.ant-phone/history
the last dialed numbers
.TP
.I ~/.ant-phone/options
user specific options file
.TP
.I ~/.ant-phone/callerid
saved history of incoming and outgoing calls
.SH BUGS
The GTK+ main loop consumes all the system CPU time. This is due to the Linux kernel select() call consuming the time while waiting for a completed data block. This only appears with some Linux kernel OSS drivers, not with ALSA.
.SH AUTHORS
ANT was developed by Roland Stigge <stigge@antcom.de>, based on ideas from IVCALL, Copyright 2002 Lennart Poettering. G.711 handling by Sun Microsystems. Contributions by Joerg Mayer <jmayer@loplof.de>, Lars Volkhardt <Lars.Volkhardt@uni-konstanz.de>.

19
po/.gitignore vendored Normal file
View File

@ -0,0 +1,19 @@
Makefile.in.in
Makevars.template
POTFILES
Rules-quot
*.gmo
boldquot.sed
en@boldquot.header
en@boldquot.insert-header
en@boldquot.po
en@quot.header
en@quot.insert-header
en@quot.po
ant-phone.pot
insert-header.sin
quot.sed
remove-potcdate.sed
remove-potcdate.sin
stamp-po

3
po/LINGUAS Normal file
View File

@ -0,0 +1,3 @@
# Set of available languages.
en@quot en@boldquot
de fr it nl ro sv tr vi

41
po/Makevars Normal file
View File

@ -0,0 +1,41 @@
# Makefile variables for PO directory in any package using GNU gettext.
# Usually the message domain is the same as the package name.
DOMAIN = $(PACKAGE)
# These two variables depend on the location of this directory.
subdir = po
top_builddir = ..
# These options get passed to xgettext.
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --from-code=ISO-8859-15
# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
# package. (Note that the msgstr strings, extracted from the package's
# sources, belong to the copyright holder of the package.) Translators are
# expected to transfer the copyright for their translations to this person
# or entity, or to disclaim their copyright. The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
COPYRIGHT_HOLDER = Roland Stigge
# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
# in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
# understood.
# - Strings which make invalid assumptions about notation of date, time or
# money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS = stigge@antcom.de
# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used. It is usually empty.
EXTRA_LOCALE_CATEGORIES =

24
po/POTFILES.in Normal file
View File

@ -0,0 +1,24 @@
# List of source files containing translatable strings.
# Copyright (C) 2003 Roland Stigge
src/ant-phone.c
src/callerid.c
src/calleridlexer.l
src/calleridparser.y
src/client.c
src/controlpad.c
src/fxgenerator.c
src/gtk.c
src/gtksettings.c
src/isdn.c
src/llcheck.c
src/mediation.c
src/isdnlexer.l
src/isdnparser.y
src/recording.c
src/server.c
src/session.c
src/settings.c
src/sound.c
src/util.c

669
po/de.po Normal file
View File

@ -0,0 +1,669 @@
# German translation of the ant-phone package
# Copyright (C) 2003 Roland Stigge
# This file is distributed under the same license as the ant-phone package.
# Roland Stigge <stigge@antcom.de>, 2003
#
msgid ""
msgstr ""
"Project-Id-Version: ant-phone 0.1.2\n"
"Report-Msgid-Bugs-To: stigge@antcom.de\n"
"POT-Creation-Date: 2004-04-03 18:51+0200\n"
"PO-Revision-Date: 2003-06-29 18:01+ZONE\n"
"Last-Translator: Roland Stigge <stigge@antcom.de>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-15\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/ant-phone.c:170
#, c-format
msgid ""
"Usage: %s [OPTION...]\n"
"\n"
"Options:\n"
" -h, --help Show this help message\n"
" -v, --version Print version information\n"
" -r, --cleanup Remove stale socket file (left by accident by\n"
" previous run)\n"
" -d, --debug[=level] Print additional runtime debugging data to stdout\n"
" level = 1..2\n"
" -i, --soundin=DEVICE OSS compatible device for input (recording),\n"
" default: /dev/dsp\n"
" -o, --soundout=DEVICE OSS compatible device for output (playback),\n"
" default: /dev/dsp\n"
" -m, --msn=MSN identifying MSN (for outgoing calls), 0 for "
"master\n"
" MSN of this termination/port\n"
" default: 0\n"
" -l, --msns=MSNS MSNs to listen on, semicolon-separated list or "
"'*'\n"
" default: *\n"
" -c, --call=NUMBER Call specified number\n"
"\n"
"Note: If arguments of --soundin and --soundout are equal, a full duplex\n"
" sound device is needed.\n"
msgstr ""
"Aufruf: %s [OPTION...]\n"
"\n"
"Optionen:\n"
" -h, --help Diese Hilfe ausgeben\n"
" -v, --version Versionsinformation ausgeben\n"
" -r, --cleanup Alte Socketdatei löschen (evtl. aus Versehen vom\n"
" vorigen Aufruf übrig gelassen)\n"
" -d, --debug[=level] Zusätzliche Testinformationen auf Standardausgabe\n"
" ausgeben (level = 1..2)\n"
" -i, --soundin=DEVICE OSS-kompatibles Gerät für die Eingabe (Aufnahme),\n"
" Voreinstellung: /dev/dsp\n"
" -o, --soundout=DEVICE OSS-kompatibles Gerät für die Ausgabe "
"(Wiedergabe),\n"
" Voreinstellung: /dev/dsp\n"
" -m, --msn=MSN identifizierende MSN (für abgehende Rufe), 0 für\n"
" Haupt-MSN dieses Anschlusses,\n"
" Voreinstellung: 0\n"
" -l, --msns=MSNS MSNs, auf welche reagiert wird, Strichpunkt-\n"
" getrennte Liste oder '*',\n"
" Voreinstellung: *\n"
" -c, --call=NUMBER Angegebene Nummer anrufen\n"
"\n"
"Anmerkung: Wenn die Argumente von --soundin und --soundout gleich sind, "
"wird\n"
" ein Full-Duplex- (/Zwei-Wege-) Gerät verwendet.\n"
#: src/ant-phone.c:221
#, c-format
msgid "Calling %s... "
msgstr "Rufe %s ... "
#: src/ant-phone.c:225
#, c-format
msgid "successful.\n"
msgstr "erfolgreich.\n"
#: src/callerid.c:131
msgid "Delete Entry"
msgstr "Lösche Zeile"
#: src/callerid.c:143
msgid ""
"Are you sure you want to\n"
"delete this entry?"
msgstr ""
"Wollen Sie diesen Eintrag\n"
"wirklich löschen?"
#: src/callerid.c:148
msgid "Delete recording"
msgstr "Lösche Aufnahme"
#: src/callerid.c:266
#, c-format
msgid "Enter the base filename for %s file"
msgstr "Basisdateiname für die %s Datei"
#: src/callerid.c:312
msgid "Do you really want to delete this recording?"
msgstr "Wollen Sie diese Aufnahme wirklich löschen?"
#: src/callerid.c:336 src/callerid.c:362
msgid "/_Playback"
msgstr "/_Wiedergabe"
#: src/callerid.c:337 src/callerid.c:366
msgid "/_Save as..."
msgstr "/_Sichern unter..."
#: src/callerid.c:338 src/callerid.c:370
msgid "/Delete _Recording"
msgstr "/Lösche _Aufnahme"
#: src/callerid.c:340 src/callerid.c:374
msgid "/_Delete Row"
msgstr "/_Lösche Zeile"
#: src/callerid.c:423 src/gtksettings.c:455
msgid "Caller ID"
msgstr "Caller ID"
#: src/callerid.c:426
msgid "Date/Time"
msgstr "Datum/Zeit"
#: src/callerid.c:427
msgid "Type"
msgstr "Typ"
#: src/callerid.c:428
msgid "From"
msgstr "Von"
#: src/callerid.c:429
msgid "To"
msgstr "Nach"
#: src/callerid.c:430
msgid "Duration"
msgstr "Dauer"
#: src/callerid.c:759
msgid "(UNKNOWN)"
msgstr "(UNBEKANNT)"
#: src/callerid.c:828
#, c-format
msgid "ANT: %d unanswered"
msgstr "ANT: %d unbeantwortet"
#: src/controlpad.c:101
#, c-format
msgid "Preset %c"
msgstr "Kurzwahl %c"
#: src/controlpad.c:108
#, c-format
msgid "Please input new preset data for button %c:"
msgstr "Bitte geben Sie die neue Kurzwahlsequenz für Taste %c ein:"
#: src/controlpad.c:121
msgid "Name:"
msgstr "Name:"
#: src/controlpad.c:124 src/gtk.c:561
msgid "Number:"
msgstr "Nummer:"
#: src/controlpad.c:144 src/gtk.c:212 src/gtk.c:331 src/gtk.c:408
#: src/gtksettings.c:571 src/llcheck.c:422
msgid "OK"
msgstr "OK"
#: src/controlpad.c:157 src/gtksettings.c:616 src/session.c:68
msgid "Cancel"
msgstr "Abbruch"
#: src/controlpad.c:315
msgid "Backspace"
msgstr "Rückschritt"
#: src/controlpad.c:315
msgid "Preset 1"
msgstr "Kurzwahl 1"
#: src/controlpad.c:316
msgid "Clear Number"
msgstr "Nummer rücksetzen"
#: src/controlpad.c:316
msgid "Preset 2"
msgstr "Kurzwahl 2"
#: src/controlpad.c:317
msgid "Redial"
msgstr "Wahlwiederholung"
#: src/controlpad.c:317
msgid "Preset 3"
msgstr "Kurzwahl 3"
#: src/controlpad.c:318
msgid "Mute Microphone"
msgstr "Mikro stummschalten"
#: src/controlpad.c:318
msgid "Preset 4"
msgstr "Kurzwahl 4"
#: src/controlpad.c:351
msgid "Control"
msgstr "Steuerung"
#: src/controlpad.c:423
msgid "Recording"
msgstr "Aufnahme"
#: src/controlpad.c:434
msgid "Record to file"
msgstr "In Datei aufnehmen"
#: src/controlpad.c:445
msgid "Record local channel"
msgstr "lokalen Kanal aufnehmen"
#: src/controlpad.c:456
msgid "Record remote channel"
msgstr "entfernten Kanal aufnehmen"
#: src/gtk.c:230 src/gtksettings.c:229
msgid "ANT Note"
msgstr "ANT Notiz"
#: src/gtk.c:231
msgid ""
"Can't open audio device.\n"
"Please stop other applications using\n"
"the audio device(s) or check your\n"
"device settings and try again."
msgstr ""
"Kann das Tonausgabegerät nicht öffnen.\n"
"Bitte halten Sie andere Programme,\n"
"welche das Gerät / die Geräte verwenden, an,\n"
"oder prüfen Sie die Geräteeinstellungen,\n"
"und versuchen Sie es erneut."
#: src/gtk.c:260
msgid "Sound input device:"
msgstr "Toneingabegerät:"
#: src/gtk.c:261
msgid "Input speed:"
msgstr "Eingabegeschwindigkeit:"
#: src/gtk.c:261 src/gtk.c:264 src/gtk.c:265 src/gtk.c:267 src/gtk.c:271
#: src/gtk.c:274 src/gtk.c:275 src/gtk.c:277
msgid "[inactive]"
msgstr "[inaktiv]"
#: src/gtk.c:263
msgid "Input sample size (bits):"
msgstr "Eingabewortbreite (Bits):"
#: src/gtk.c:265 src/gtk.c:275
msgid "Input fragment size (samples):"
msgstr "Eingabefragmentgröße (Worte):"
#: src/gtk.c:267
msgid "Input channels:"
msgstr "Eingabekanäle:"
#: src/gtk.c:270
msgid "Sound output device:"
msgstr "Tonausgabegerät:"
#: src/gtk.c:271
msgid "Output speed:"
msgstr "Ausgabegeschwindigkeit:"
#: src/gtk.c:273
msgid "Output sample size (bits):"
msgstr "Ausgabewortbreite (Bits):"
#: src/gtk.c:277
msgid "Output channels:"
msgstr "Ausgabekanäle:"
#: src/gtk.c:280
msgid "ISDN device:"
msgstr "ISDN-Gerät:"
#: src/gtk.c:281
msgid "ISDN speed (samples):"
msgstr "ISDN-Geschwindigkeit (Worte):"
#: src/gtk.c:282
msgid "ISDN sample size (bits):"
msgstr "ISDN-Wortbreite (Bits):"
#: src/gtk.c:283
msgid "ISDN fragment size (bytes):"
msgstr "ISDN-Fragmentgröße (Bytes):"
#: src/gtk.c:295
msgid "ANT Info"
msgstr "ANT Info"
#: src/gtk.c:366
msgid "About ANT"
msgstr "Über ANT"
#: src/gtk.c:382
#, c-format
msgid ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"This is an ISDN telephone application\n"
"written for GNU/Linux and ISDN4Linux for\n"
"communicating via a full duplex soundcard (or\n"
"multiple sound devices if you like) and an\n"
"audio capable ISDN4Linux ISDN device\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing list: ant-phone-devel@nongnu.org"
msgstr ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"Dies ist eine ISDN-Telefonanwendung, welche für\n"
"GNU/Linux und ISDN4Linux für die Kommunikation\n"
"mit einem Full-Duplex- (/Zwei-Wege-) Gerät (oder\n"
"mehreren Ton-Ein-/Ausgabegeräten) und einem\n"
"audio-fähigen ISDN4Linux-ISDN-Gerät geschrieben wurde\n"
"\n"
"Kontakt:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailingliste: ant-phone-devel@nongnu.org"
#: src/gtk.c:420
msgid "ANT License"
msgstr "ANT Lizenz"
#: src/gtk.c:421
msgid ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
msgstr ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"Dieses Programm ist Freie Software; Sie können es unter den\n"
"Bedingungen der GNU General Public License Version 2 oder (nach\n"
"Belieben) neuer, wie von der Free Software Foundation\n"
"veröffentlicht, weitergeben und/oder modifizieren.\n"
"\n"
"Dieses Programm wird in der Hoffnung, dass es nützlich sein wird,\n"
"herausgegeben. Es wird jedoch KEINE GARANTIE übernommen. Selbst\n"
"die implizite Garantie der MARKTGÄNGIGKEIT oder TAUGLICHKEIT FÜR\n"
"EINEN BESTIMMTEN ZWECK kann nicht gewährleistet werden.\n"
"Siehe GNU General Public License für Details.\n"
"\n"
"Sie sollten eine Kopie der GNU General Public License\n"
"zusammen mit diesem Programm erhalten haben. Falls nicht,\n"
"schreiben Sie bitte an die\n"
"\n"
"Free Software Foundation, Inc.\n"
"59 Temple Place - Suite 330\n"
"Boston\n"
"MA 02111-1307\n"
"USA."
#: src/gtk.c:454
msgid "/Phon_e"
msgstr "/_Telefon"
#: src/gtk.c:455
msgid "/Phone/_Info Window"
msgstr "/Telefon/_Info Fenster"
#: src/gtk.c:456 src/gtk.c:504
msgid "/Phone/_Line Level Check"
msgstr "/Telefon/_Pegelkontrolle"
#: src/gtk.c:458
msgid "/Phone/"
msgstr "/Telefon/"
#: src/gtk.c:459
msgid "/Phone/_Quit"
msgstr "/Telefon/_Beenden"
#: src/gtk.c:461
msgid "/_View"
msgstr "/_Ansicht"
#: src/gtk.c:462 src/gtk.c:492
msgid "/View/_Caller ID Monitor"
msgstr "/Ansicht/_Caller-ID-Anzeige"
#: src/gtk.c:464 src/gtk.c:495
msgid "/View/_Line Level Meters"
msgstr "/Ansicht/_Pegelanzeigen"
#: src/gtk.c:466 src/gtk.c:498
msgid "/View/Control _Pad"
msgstr "/Ansicht/_Steuerfeld"
#: src/gtk.c:468
msgid "/_Options"
msgstr "/_Optionen"
#: src/gtk.c:469 src/gtk.c:501
msgid "/Options/_Settings"
msgstr "/Optionen/_Einstellungen"
#: src/gtk.c:471
msgid "/_Help"
msgstr "/_Hilfe"
#: src/gtk.c:472
msgid "/Help/_About"
msgstr "/Hilfe/_Über"
#: src/gtk.c:473
msgid "/Help/_License"
msgstr "/Hilfe/_Lizenz"
#: src/gtk.c:551 src/gtksettings.c:431 src/session.c:68
msgid "Dialing"
msgstr "Wählen"
#: src/gtk.c:783 src/gtk.c:784
msgid "MUTED"
msgstr "STUMM"
#: src/gtksettings.c:230
msgid "Bad isdn/sound device settings, please try again."
msgstr ""
"Ungültige Einstellungen der ISDN/Ton-Ein-/Ausgabegeräte, bitte neu versuchen."
#: src/gtksettings.c:293
msgid "ANT Settings"
msgstr "ANT Einstellungen"
#: src/gtksettings.c:306
msgid "Application"
msgstr "Anwendung"
#: src/gtksettings.c:308
msgid "Options"
msgstr "Optionen"
#: src/gtksettings.c:320
msgid "Save options on exit"
msgstr "Beim Beenden Optionen sichern"
#: src/gtksettings.c:327
msgid "Popup main window on incoming call"
msgstr "Bei kommenden Rufen in den Vordergrund bringen"
#: src/gtksettings.c:333
msgid "Execute on incoming call:"
msgstr "Bei kommenden Rufen ausführen:"
#: src/gtksettings.c:344
msgid "Recording Format"
msgstr "Aufnahmeformat"
#: src/gtksettings.c:354
msgid "Microsoft WAV, uLaw"
msgstr ""
#: src/gtksettings.c:364
msgid "Microsoft WAV, 16-bit signed"
msgstr ""
#: src/gtksettings.c:374
msgid "Apple/SGI AIFF, uLaw"
msgstr ""
#: src/gtksettings.c:384
msgid "Apple/SGI AIFF, 16-bit signed"
msgstr ""
#: src/gtksettings.c:397
msgid "Phone"
msgstr "Telefon"
#: src/gtksettings.c:399
msgid "ISDN"
msgstr ""
#: src/gtksettings.c:411
msgid "Identifying MSN:"
msgstr "Identifizierende MSN:"
#: src/gtksettings.c:421
msgid "Listen to MSNs:"
msgstr "Höre auf MSNs:"
#: src/gtksettings.c:443
msgid "Dial history size:"
msgstr "Größe der Wählhistorie:"
#: src/gtksettings.c:467
msgid "Maximum CID rows:"
msgstr "Maximale CID-Zeilen:"
#: src/gtksettings.c:475 src/gtksettings.c:503
msgid "[no limit]"
msgstr "[keine Begrenzung]"
#: src/gtksettings.c:484
msgid "Read isdnlog data on startup"
msgstr "isdnlog-Daten beim Start lesen"
#: src/gtksettings.c:491
msgid "Maximum days to read from isdnlog:"
msgstr "Maximale Anzahl Tage, welche von isdnlog gelesen werden:"
#: src/gtksettings.c:520
msgid "Sound Devices"
msgstr "Ton-Ein-/Ausgabegeräte"
#: src/gtksettings.c:522
msgid "OSS"
msgstr ""
#: src/gtksettings.c:534
msgid "Input sound device:"
msgstr "Ton-Eingabegerät:"
#: src/gtksettings.c:546
msgid "Output sound device:"
msgstr "Ton-Ausgabegerät"
#: src/gtksettings.c:559
msgid "Release unused devices"
msgstr "Unbenutzte Ton-Ein-/Ausgabegeräte freigeben"
#: src/gtksettings.c:609
msgid "Save"
msgstr "Sichern"
#: src/llcheck.c:371
msgid "Line Level Check"
msgstr "Pegelkontrolle"
#: src/llcheck.c:383
msgid ""
"Please check the line input level\n"
"and adjust it using your favorite\n"
"mixer application.\n"
"You can also play a sound\n"
"to test the sound output."
msgstr ""
"Bitte testen Sie den Pegel\n"
"und justieren Sie ihn mit dem\n"
"Mixerprogramm Ihrer Wahl.\n"
"Sie können auch einen Ton ausgeben\n"
"lassen, um die Klangausgabe zu prüfen."
#: src/llcheck.c:405
msgid "Play sound"
msgstr "Ton ausgeben"
#: src/session.c:65
msgid "Ready"
msgstr "Bereit"
#: src/session.c:65
msgid "Dial"
msgstr "Wählen"
#: src/session.c:65 src/session.c:69 src/session.c:70
msgid "Hang up"
msgstr "Auflegen"
#: src/session.c:66 src/session.c:67
msgid "RING"
msgstr "KLINGELN"
#: src/session.c:66 src/session.c:67
msgid "Answer"
msgstr "Antworten"
#: src/session.c:66 src/session.c:67
msgid "Reject"
msgstr "Ablehnen"
#: src/session.c:68 src/session.c:69 src/session.c:70 src/session.c:71
msgid "Pick up"
msgstr "Abheben"
#: src/session.c:69
msgid "B-Channel open"
msgstr "B-Kanal offen"
#: src/session.c:70
msgid "Setup"
msgstr "Einstellungen"
#: src/session.c:71
msgid "Playback"
msgstr "/Wiedergabe"
#: src/session.c:71
msgid "Stop"
msgstr "Einstellungen"
#: src/session.c:377
#, c-format
msgid "Preset %d"
msgstr "Kurzwahl %d"
#: src/session.c:699
msgid "(HW ERROR)"
msgstr "(HW FEHLER)"
#: src/session.c:1000
msgid "Audio OFF"
msgstr "Ton AUS"
#: src/session.c:1000
msgid "Audio ON"
msgstr "Ton AN"
#: src/session.c:1097
msgid "(BUSY)"
msgstr "(BESETZT)"
#: src/session.c:1103
msgid "(TIMEOUT)"
msgstr ""
#: src/session.c:1139
msgid "(RUNG)"
msgstr "(RUF)"
#: src/session.c:1381
msgid "(ABORTED)"
msgstr "(ABGEBROCHEN)"
#: src/session.c:1389
msgid "(REJECTED)"
msgstr "(ABGELEHNT)"

662
po/fr.po Normal file
View File

@ -0,0 +1,662 @@
# Messages français pour GNU concernant ant-phone.
# Copyright © 2004 Free Software Foundation, Inc.
# This file is distributed under the same license as the PACKAGE package.
# Michel Robitaille <robitail@IRO.UMontreal.CA>, traducteur depuis/since 1996.
#
msgid ""
msgstr ""
"Project-Id-Version: GNU ant-phone 0.1.4\n"
"Report-Msgid-Bugs-To: stigge@antcom.de\n"
"POT-Creation-Date: 2004-04-03 18:51+0200\n"
"PO-Revision-Date: 2004-05-10 08:00-0500\n"
"Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>\n"
"Language-Team: French <traduc@traduc.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: src/ant-phone.c:170
#, c-format
msgid ""
"Usage: %s [OPTION...]\n"
"\n"
"Options:\n"
" -h, --help Show this help message\n"
" -v, --version Print version information\n"
" -r, --cleanup Remove stale socket file (left by accident by\n"
" previous run)\n"
" -d, --debug[=level] Print additional runtime debugging data to stdout\n"
" level = 1..2\n"
" -i, --soundin=DEVICE OSS compatible device for input (recording),\n"
" default: /dev/dsp\n"
" -o, --soundout=DEVICE OSS compatible device for output (playback),\n"
" default: /dev/dsp\n"
" -m, --msn=MSN identifying MSN (for outgoing calls), 0 for "
"master\n"
" MSN of this termination/port\n"
" default: 0\n"
" -l, --msns=MSNS MSNs to listen on, semicolon-separated list or "
"'*'\n"
" default: *\n"
" -c, --call=NUMBER Call specified number\n"
"\n"
"Note: If arguments of --soundin and --soundout are equal, a full duplex\n"
" sound device is needed.\n"
msgstr ""
"Usage: %s [OPTION...]\n"
"\n"
"Options:\n"
" -h, --help affichier l'aide-mémoire\n"
" -v, --version affichier la version du logiciel\n"
" -r, --cleanup enlever le fichier du socket figé (laissé lors\n"
" l'exécution précédente)\n"
" -d, --debug[=niveau] afficher des informations additionnelles de mises "
"au point sur stdout\n"
" niveau = 1..2\n"
" -i, --soundin=PERI PÉRIphérique compatible OSS pour la sortie "
"(enregistrement),\n"
" par défaut: /dev/dsp\n"
" -o, --soundout=PERI PÉRIphérique compatible OSS pour l'entrée "
"(écoute),\n"
" par défaut: /dev/dsp\n"
" -m, --msn=MSN identificateur MSN (pour les appels sortant), 0 "
"pour maître\n"
" MSN de terminaison/port\n"
" par défaut: 0\n"
" -l, --msns=MSNS MSNs d'écoute, liste séparée par des « ; » ou '*'\n"
" par défaut: *\n"
" -c, --call=NUMÉRO numéro d'appel spécifique\n"
"\n"
"Note: si les arguments de --soundin et --soundout sont identiques, un "
"périphérique\n"
" de son fonctionnant en mode duplex est nécessaire.\n"
#: src/ant-phone.c:221
#, c-format
msgid "Calling %s... "
msgstr "Appel en cour %s... "
#: src/ant-phone.c:225
#, c-format
msgid "successful.\n"
msgstr "succès.\n"
#: src/callerid.c:131
msgid "Delete Entry"
msgstr "Détruire l'entrée"
#: src/callerid.c:143
msgid ""
"Are you sure you want to\n"
"delete this entry?"
msgstr ""
"Êtes-vous certains de vouloir\n"
"détruire cette entrée?"
#: src/callerid.c:148
msgid "Delete recording"
msgstr "Destruction de l'enregistrement"
#: src/callerid.c:266
#, c-format
msgid "Enter the base filename for %s file"
msgstr "Fournir le nom de base du fichier %s"
#: src/callerid.c:312
msgid "Do you really want to delete this recording?"
msgstr "Désirez-vous réellement détruire cet enregistrement?"
#: src/callerid.c:336 src/callerid.c:362
msgid "/_Playback"
msgstr "/_Playback (ré-écoute"
#: src/callerid.c:337 src/callerid.c:366
msgid "/_Save as..."
msgstr "/_Sauvagarder sous..."
#: src/callerid.c:338 src/callerid.c:370
msgid "/Delete _Recording"
msgstr "/Détruire l'_Enregistrement"
#: src/callerid.c:340 src/callerid.c:374
msgid "/_Delete Row"
msgstr "/_Détruire la rangée"
#: src/callerid.c:423 src/gtksettings.c:455
msgid "Caller ID"
msgstr "Identificateur de l'appelant"
#: src/callerid.c:426
msgid "Date/Time"
msgstr "Date/Heure"
#: src/callerid.c:427
msgid "Type"
msgstr "Type"
#: src/callerid.c:428
msgid "From"
msgstr "De"
#: src/callerid.c:429
msgid "To"
msgstr "À"
#: src/callerid.c:430
msgid "Duration"
msgstr "Durée"
#: src/callerid.c:759
msgid "(UNKNOWN)"
msgstr "(INCONNU)"
#: src/callerid.c:828
#, c-format
msgid "ANT: %d unanswered"
msgstr "ANT: %d non répondus"
#: src/controlpad.c:101
#, c-format
msgid "Preset %c"
msgstr "Présélection %c"
#: src/controlpad.c:108
#, c-format
msgid "Please input new preset data for button %c:"
msgstr "SVP fournir les nouvelles données de présélection pour le bouton %c:"
#: src/controlpad.c:121
msgid "Name:"
msgstr "Nom:"
#: src/controlpad.c:124 src/gtk.c:561
msgid "Number:"
msgstr "Numéro:"
#: src/controlpad.c:144 src/gtk.c:212 src/gtk.c:331 src/gtk.c:408
#: src/gtksettings.c:571 src/llcheck.c:422
msgid "OK"
msgstr "OK"
#: src/controlpad.c:157 src/gtksettings.c:616 src/session.c:68
msgid "Cancel"
msgstr "Annuler"
#: src/controlpad.c:315
msgid "Backspace"
msgstr "Espace arrière"
#: src/controlpad.c:315
msgid "Preset 1"
msgstr "Présélection 1"
#: src/controlpad.c:316
msgid "Clear Number"
msgstr "Effacer le numéro"
#: src/controlpad.c:316
msgid "Preset 2"
msgstr "Présélection 2"
#: src/controlpad.c:317
msgid "Redial"
msgstr "Recomposer"
#: src/controlpad.c:317
msgid "Preset 3"
msgstr "Présélection 3"
#: src/controlpad.c:318
msgid "Mute Microphone"
msgstr "Éteindre le microphone"
#: src/controlpad.c:318
msgid "Preset 4"
msgstr "Présélection 4"
#: src/controlpad.c:351
msgid "Control"
msgstr "Contrôle"
#: src/controlpad.c:423
msgid "Recording"
msgstr "Enregistrement en cours"
#: src/controlpad.c:434
msgid "Record to file"
msgstr "Enregistrer dans un fichier"
#: src/controlpad.c:445
msgid "Record local channel"
msgstr "Enregister sur canal local"
#: src/controlpad.c:456
msgid "Record remote channel"
msgstr "Enregistrer sur canal distant"
#: src/gtk.c:230 src/gtksettings.c:229
msgid "ANT Note"
msgstr "Note ANT"
#: src/gtk.c:231
msgid ""
"Can't open audio device.\n"
"Please stop other applications using\n"
"the audio device(s) or check your\n"
"device settings and try again."
msgstr ""
"Ne peut ouvrir le périphérique audio.\n"
"SVP stopper les autres applications utilisant\n"
"le périphérique audio ou vérifier la\n"
"configuration du périphérique et essayer à nouveau."
#: src/gtk.c:260
msgid "Sound input device:"
msgstr "Entrée du périphérique de son:"
#: src/gtk.c:261
msgid "Input speed:"
msgstr "Vitesse d'entrée"
#: src/gtk.c:261 src/gtk.c:264 src/gtk.c:265 src/gtk.c:267 src/gtk.c:271
#: src/gtk.c:274 src/gtk.c:275 src/gtk.c:277
msgid "[inactive]"
msgstr "[inactif]"
#: src/gtk.c:263
msgid "Input sample size (bits):"
msgstr "Taille d'échantillon d'entrée (en bits):"
#: src/gtk.c:265 src/gtk.c:275
msgid "Input fragment size (samples):"
msgstr "Taille de fragment d'entrée (échantillons)"
#: src/gtk.c:267
msgid "Input channels:"
msgstr "Canaux d'entrée:"
#: src/gtk.c:270
msgid "Sound output device:"
msgstr "Sortie du périphérique de son:"
#: src/gtk.c:271
msgid "Output speed:"
msgstr "Vitesse de sortie:"
#: src/gtk.c:273
msgid "Output sample size (bits):"
msgstr "Taille d'échantillon de sortie (en bits):"
#: src/gtk.c:277
msgid "Output channels:"
msgstr "Canaux de sortie:"
#: src/gtk.c:280
msgid "ISDN device:"
msgstr "Périphérique ISDN:"
#: src/gtk.c:281
msgid "ISDN speed (samples):"
msgstr "Vitesse ISDN (échantillons):"
#: src/gtk.c:282
msgid "ISDN sample size (bits):"
msgstr "Taille d'échantillon ISDN (en bits):"
#: src/gtk.c:283
msgid "ISDN fragment size (bytes):"
msgstr "Taille de fragment ISDN (en octets):"
#: src/gtk.c:295
msgid "ANT Info"
msgstr "Info ANT"
#: src/gtk.c:366
msgid "About ANT"
msgstr "À propos de ANT"
#: src/gtk.c:382
#, c-format
msgid ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"This is an ISDN telephone application\n"
"written for GNU/Linux and ISDN4Linux for\n"
"communicating via a full duplex soundcard (or\n"
"multiple sound devices if you like) and an\n"
"audio capable ISDN4Linux ISDN device\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing list: ant-phone-devel@nongnu.org"
msgstr ""
"ANT (ANT est « Not » un Téléphone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"C'est un logiciel de téléphone ISDN\n"
"écrit pour GNU/Linux et ISDN4Linux pour\n"
"communiquer à l'aide d'une carte de son fonctionnant en mode duplex complet\n"
"( ou de multiples périphériques de son si vous le désirez) et un\n"
"périphérique audio supportant ISDN4Linux ISDN\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Liste de courriel: ant-phone-devel@nongnu.org"
#: src/gtk.c:420
msgid "ANT License"
msgstr "Licence ANT"
#: src/gtk.c:421
msgid ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
msgstr ""
"ANT (ANT est « Not » un Téléphone)\n"
"Copyright © 2002, 2003 Roland Stigge\n"
"\n"
"Ce logiciel est libre; vous pouvez le redistribuer selon les termes de la\n"
"licence GNU General Public License. AUCUNE garantie n'est donnée.\n"
"tel que publiée par la Free Software Foundation; tel que la version 2\n"
"de la licence ou (selon votre choix) n'importe quelle version subséquente.\n"
"\n"
"Ce logiciel est distribué dans l'espoir qu'il soit utile,\n"
"mais AUCUNE garantie n'est donnée tant pour des raisons COMMERCIALES que\n"
"pour RÉPONDRE À UN BESOIN PARTICULIER. Consulter la licence\n"
"Licence Publique Générale GNU pour plus de détails.\n"
"\n"
"Vous devriez avoir reçu copie de la Licence Publique Générale de GNU\n"
"avec GNU Anubis; sinon, écrire à la Free Software Foundation, Inc.,\n"
"59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
#: src/gtk.c:454
msgid "/Phon_e"
msgstr "/_Téléphone"
#: src/gtk.c:455
msgid "/Phone/_Info Window"
msgstr "/Téléphone/_Fenêtre Info"
#: src/gtk.c:456 src/gtk.c:504
msgid "/Phone/_Line Level Check"
msgstr "/Téléphone/_Vérification du niveau de la ligne"
#: src/gtk.c:458
msgid "/Phone/"
msgstr "/Téléphone/"
#: src/gtk.c:459
msgid "/Phone/_Quit"
msgstr "/Téléphone/_Quitter"
#: src/gtk.c:461
msgid "/_View"
msgstr "/_Visionner"
#: src/gtk.c:462 src/gtk.c:492
msgid "/View/_Caller ID Monitor"
msgstr "/Visionner/_ID appelant"
#: src/gtk.c:464 src/gtk.c:495
msgid "/View/_Line Level Meters"
msgstr "/Visionner/_Niveau de ligne"
#: src/gtk.c:466 src/gtk.c:498
msgid "/View/Control _Pad"
msgstr "/Visionner/_Panneau de contrôle"
#: src/gtk.c:468
msgid "/_Options"
msgstr "/_Options"
#: src/gtk.c:469 src/gtk.c:501
msgid "/Options/_Settings"
msgstr "/Options/_Configurations"
#: src/gtk.c:471
msgid "/_Help"
msgstr "/_Aide"
#: src/gtk.c:472
msgid "/Help/_About"
msgstr "/AIde/_A propos"
#: src/gtk.c:473
msgid "/Help/_License"
msgstr "/Aide/_Licence"
#: src/gtk.c:551 src/gtksettings.c:431 src/session.c:68
msgid "Dialing"
msgstr "Composition en cours"
#: src/gtk.c:783 src/gtk.c:784
msgid "MUTED"
msgstr "SILENCIEUX"
#: src/gtksettings.c:230
msgid "Bad isdn/sound device settings, please try again."
msgstr "Mauvais ISDN/configuration du périphérique, svp essayez à nouveau"
#: src/gtksettings.c:293
msgid "ANT Settings"
msgstr "Configurations ANT"
#: src/gtksettings.c:306
msgid "Application"
msgstr "Application"
#: src/gtksettings.c:308
msgid "Options"
msgstr "Options"
#: src/gtksettings.c:320
msgid "Save options on exit"
msgstr "Sauvegarder les options à la fin de l'exécution"
#: src/gtksettings.c:327
msgid "Popup main window on incoming call"
msgstr "Popup la fenêtre principale lors de l'arrivée d'un appel"
#: src/gtksettings.c:333
msgid "Execute on incoming call:"
msgstr "Éxécuter lors d'un appel entrant:"
#: src/gtksettings.c:344
msgid "Recording Format"
msgstr "Formet d'enregistement"
#: src/gtksettings.c:354
msgid "Microsoft WAV, uLaw"
msgstr "WAV Microsoft, uLaw"
#: src/gtksettings.c:364
msgid "Microsoft WAV, 16-bit signed"
msgstr "WAV Microsoft, 16 bits signés"
#: src/gtksettings.c:374
msgid "Apple/SGI AIFF, uLaw"
msgstr "Aple/SGI AIFF, uLaw"
#: src/gtksettings.c:384
msgid "Apple/SGI AIFF, 16-bit signed"
msgstr "Apple/SGI AIFF, 16 bits signés"
#: src/gtksettings.c:397
msgid "Phone"
msgstr "Téléphone"
#: src/gtksettings.c:399
msgid "ISDN"
msgstr "ISDN"
#: src/gtksettings.c:411
msgid "Identifying MSN:"
msgstr "MSN identifiant:"
#: src/gtksettings.c:421
msgid "Listen to MSNs:"
msgstr "Écoute des MSN:"
#: src/gtksettings.c:443
msgid "Dial history size:"
msgstr "Taille du fichier hiostorique des appels:"
#: src/gtksettings.c:467
msgid "Maximum CID rows:"
msgstr "Maximum de rangées CID:"
#: src/gtksettings.c:475 src/gtksettings.c:503
msgid "[no limit]"
msgstr "[pas de limite]"
#: src/gtksettings.c:484
msgid "Read isdnlog data on startup"
msgstr "Lire le journal isdnlog lors du démarrage"
#: src/gtksettings.c:491
msgid "Maximum days to read from isdnlog:"
msgstr "Nombre de jours maximum pour lire à partir du journal isdnlog:"
#: src/gtksettings.c:520
msgid "Sound Devices"
msgstr "Périphérique de son"
#: src/gtksettings.c:522
msgid "OSS"
msgstr "OSS"
#: src/gtksettings.c:534
msgid "Input sound device:"
msgstr "Périphérique d'entrée de son:"
#: src/gtksettings.c:546
msgid "Output sound device:"
msgstr "Périphérique de sortie de son:"
#: src/gtksettings.c:559
msgid "Release unused devices"
msgstr "Relâcher les périphériques non utilisés"
#: src/gtksettings.c:609
msgid "Save"
msgstr "Sauvegader"
#: src/llcheck.c:371
msgid "Line Level Check"
msgstr "Vérification du niveau des lignes"
#: src/llcheck.c:383
msgid ""
"Please check the line input level\n"
"and adjust it using your favorite\n"
"mixer application.\n"
"You can also play a sound\n"
"to test the sound output."
msgstr ""
"SVP vérifier le niveau de la ligne d'entrée\n"
"et ajustez le pour utiliser votre application de mixage favorite.\n"
"Vous pouvcz aussi faire l'écoute d'un fichier de son pour tester\n"
"la sortie de son."
#: src/llcheck.c:405
msgid "Play sound"
msgstr "Faire entendre le son"
#: src/session.c:65
msgid "Ready"
msgstr "Prêt"
#: src/session.c:65
msgid "Dial"
msgstr "Composer"
#: src/session.c:65 src/session.c:69 src/session.c:70
msgid "Hang up"
msgstr "Raccrocher"
#: src/session.c:66 src/session.c:67
msgid "RING"
msgstr "SONERIE"
#: src/session.c:66 src/session.c:67
msgid "Answer"
msgstr "Répondre"
#: src/session.c:66 src/session.c:67
msgid "Reject"
msgstr "Rejetr"
#: src/session.c:68 src/session.c:69 src/session.c:70 src/session.c:71
msgid "Pick up"
msgstr "Décrocher"
#: src/session.c:69
msgid "B-Channel open"
msgstr "Canal-B ouvert"
#: src/session.c:70
msgid "Setup"
msgstr "Configuration"
#: src/session.c:71
msgid "Playback"
msgstr "Ré-écoute"
#: src/session.c:71
msgid "Stop"
msgstr "Stopper"
#: src/session.c:377
#, c-format
msgid "Preset %d"
msgstr "Préselection %d"
#: src/session.c:699
msgid "(HW ERROR)"
msgstr "(ERREUR matérielle)"
#: src/session.c:1000
msgid "Audio OFF"
msgstr "Audio à l'arrêt"
#: src/session.c:1000
msgid "Audio ON"
msgstr "Audio en marche"
#: src/session.c:1097
msgid "(BUSY)"
msgstr "(OCCUPÉ)"
#: src/session.c:1103
msgid "(TIMEOUT)"
msgstr "(MINUTERIE EXPIRÉE)"
#: src/session.c:1139
msgid "(RUNG)"
msgstr "(A SONNÉ)"
#: src/session.c:1381
msgid "(ABORTED)"
msgstr "(ARRÊT DEMANDÉ)"
#: src/session.c:1389
msgid "(REJECTED)"
msgstr "(REJETÉ)"

661
po/it.po Normal file
View File

@ -0,0 +1,661 @@
# Messaggi italiani riguardanti GNU ant-phone
# Messages français pour GNU concernant ant-phone.
# Copyright © 2004 Free Software Foundation, Inc.
# This file is distributed under the same license as the PACKAGE package.
# Luca Mariot <rymoah@yahoo.it>
msgid ""
msgstr ""
"Project-Id-Version: GNU ant-phone 0.1.12\n"
"Report-Msgid-Bugs-To: stigge@antcom.de\n"
"POT-Creation-Date: 2004-04-03 18:51+0200\n"
"PO-Revision-Date: 2007-01-06 08:00-0500\n"
"Last-Translator: Luca Mariot <rymoah@yahoo.it>\n"
"Language-Team: Italian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: src/ant-phone.c:170
#, c-format
msgid ""
"Usage: %s [OPTION...]\n"
"\n"
"Options:\n"
" -h, --help Show this help message\n"
" -v, --version Print version information\n"
" -r, --cleanup Remove stale socket file (left by accident by\n"
" previous run)\n"
" -d, --debug[=level] Print additional runtime debugging data to stdout\n"
" level = 1..2\n"
" -i, --soundin=DEVICE OSS compatible device for input (recording),\n"
" default: /dev/dsp\n"
" -o, --soundout=DEVICE OSS compatible device for output (playback),\n"
" default: /dev/dsp\n"
" -m, --msn=MSN identifying MSN (for outgoing calls), 0 for "
"master\n"
" MSN of this termination/port\n"
" default: 0\n"
" -l, --msns=MSNS MSNs to listen on, semicolon-separated list or "
"'*'\n"
" default: *\n"
" -c, --call=NUMBER Call specified number\n"
"\n"
"Note: If arguments of --soundin and --soundout are equal, a full duplex\n"
" sound device is needed.\n"
msgstr ""
"Usage: %s [OPZIONE...]\n"
"\n"
"Options:\n"
" -h, --help mostra questo messaggio di aiuto\n"
" -v, --version mostra informazioni sulla versione\n"
" -r, --cleanup rimuove il vecchio file di socket (lasciato\n"
" accidentalmente da esecuzioni precedenti)\n"
" -d, --debug[=livello] stampa dati di debug aggiuntivi su stdout\n"
" livello = 1..2\n"
" -i, --soundin=PERI PERIeriferica compatibile con OSS per l'entrata "
"(registrazione),\n"
" per default: /dev/dsp\n"
" -o, --soundout=PERI PERIferica compatibile con OSS per l'uscita "
"(ascolto),\n"
" per default: /dev/dsp\n"
" -m, --msn=MSN MSN identificativo (per le chiamate uscenti), 0 "
"per il master\n"
" MSN di terminazione/port\n"
" per default: 0\n"
" -l, --msns=MSNS MSNs d'ascolto, lista separata da « ; » ou '*'\n"
" per default: *\n"
" -c, --call=NUMERO Chiama il numero specifico\n"
"\n"
"Nota: se gli argomenti di --soundin e --soundout sono uguali, è necessaria\n"
" una scheda audio full-duplex.\n"
#: src/ant-phone.c:221
#, c-format
msgid "Calling %s... "
msgstr "Chiamata in corso %s... "
#: src/ant-phone.c:225
#, c-format
msgid "successful.\n"
msgstr "eseguito.\n"
#: src/callerid.c:131
msgid "Delete Entry"
msgstr "Cancellare Voce"
#: src/callerid.c:143
msgid ""
"Are you sure you want to\n"
"delete this entry?"
msgstr ""
"Siete sicuri di voler\n"
"cancellare questa voce?"
#: src/callerid.c:148
msgid "Delete recording"
msgstr "Cancellazione della registrazione"
#: src/callerid.c:266
#, c-format
msgid "Enter the base filename for %s file"
msgstr "Inserire il nome di base del file %s"
#: src/callerid.c:312
msgid "Do you really want to delete this recording?"
msgstr "Volete davvero cancellare questa registrazione?"
#: src/callerid.c:336 src/callerid.c:362
msgid "/_Playback"
msgstr "/_Playback (riascolta"
#: src/callerid.c:337 src/callerid.c:366
msgid "/_Save as..."
msgstr "/_Salva con nome..."
#: src/callerid.c:338 src/callerid.c:370
msgid "/Delete _Recording"
msgstr "/Cancellare la _Registrazione"
#: src/callerid.c:340 src/callerid.c:374
msgid "/_Delete Row"
msgstr "/_Cancellare riga"
#: src/callerid.c:423 src/gtksettings.c:455
msgid "Caller ID"
msgstr "Identificativo del chiamante"
#: src/callerid.c:426
msgid "Date/Time"
msgstr "Data/Ora"
#: src/callerid.c:427
msgid "Type"
msgstr "Tipo"
#: src/callerid.c:428
msgid "From"
msgstr "Da"
#: src/callerid.c:429
msgid "To"
msgstr "A"
#: src/callerid.c:430
msgid "Duration"
msgstr "Durata"
#: src/callerid.c:759
msgid "(UNKNOWN)"
msgstr "(IGNOTO)"
#: src/callerid.c:828
#, c-format
msgid "ANT: %d unanswered"
msgstr "ANT: %d chiamata non risposta"
#: src/controlpad.c:101
#, c-format
msgid "Preset %c"
msgstr "Preselezione %c"
#: src/controlpad.c:108
#, c-format
msgid "Please input new preset data for button %c:"
msgstr "Prego inserire i nuovi dati per il pulsante di preset %c:"
#: src/controlpad.c:121
msgid "Name:"
msgstr "Nome:"
#: src/controlpad.c:124 src/gtk.c:561
msgid "Number:"
msgstr "Numero:"
#: src/controlpad.c:144 src/gtk.c:212 src/gtk.c:331 src/gtk.c:408
#: src/gtksettings.c:571 src/llcheck.c:422
msgid "OK"
msgstr "OK"
#: src/controlpad.c:157 src/gtksettings.c:616 src/session.c:68
msgid "Cancel"
msgstr "Annulla"
#: src/controlpad.c:315
msgid "Backspace"
msgstr "Backspace"
#: src/controlpad.c:315
msgid "Preset 1"
msgstr "Preselezione 1"
#: src/controlpad.c:316
msgid "Clear Number"
msgstr "Cancellare numero"
#: src/controlpad.c:316
msgid "Preset 2"
msgstr "Preselezione 2"
#: src/controlpad.c:317
msgid "Redial"
msgstr "Ricomponi"
#: src/controlpad.c:317
msgid "Preset 3"
msgstr "Preselezione 3"
#: src/controlpad.c:318
msgid "Mute Microphone"
msgstr "Setta a muto il microfono"
#: src/controlpad.c:318
msgid "Preset 4"
msgstr "Preselezione 4"
#: src/controlpad.c:351
msgid "Control"
msgstr "Controllo"
#: src/controlpad.c:423
msgid "Recording"
msgstr "Registrazione in corso..."
#: src/controlpad.c:434
msgid "Record to file"
msgstr "Registra in un file"
#: src/controlpad.c:445
msgid "Record local channel"
msgstr "Registra su canale locale"
#: src/controlpad.c:456
msgid "Record remote channel"
msgstr "Registra su canale remoto"
#: src/gtk.c:230 src/gtksettings.c:229
msgid "ANT Note"
msgstr "Nota di ANT"
#: src/gtk.c:231
msgid ""
"Can't open audio device.\n"
"Please stop other applications using\n"
"the audio device(s) or check your\n"
"device settings and try again."
msgstr ""
"Impossibile aprire la periferica audio.\n"
"Prego chiudere gli altri programmi che usano\n"
"la scheda audio o verificarne\n"
"la configurazione e riprovare."
#: src/gtk.c:260
msgid "Sound input device:"
msgstr "Periferica per l'input audio:"
#: src/gtk.c:261
msgid "Input speed:"
msgstr "Velocità d'input:"
#: src/gtk.c:261 src/gtk.c:264 src/gtk.c:265 src/gtk.c:267 src/gtk.c:271
#: src/gtk.c:274 src/gtk.c:275 src/gtk.c:277
msgid "[inactive]"
msgstr "[inattivo]"
#: src/gtk.c:263
msgid "Input sample size (bits):"
msgstr "Dimensione campione d'input (in bit):"
#: src/gtk.c:265 src/gtk.c:275
msgid "Input fragment size (samples):"
msgstr "Dimensione frammento per l'input (campioni):"
#: src/gtk.c:267
msgid "Input channels:"
msgstr "Canali d'input:"
#: src/gtk.c:270
msgid "Sound output device:"
msgstr "Periferica per l'output audio:"
#: src/gtk.c:271
msgid "Output speed:"
msgstr "Velocità d'output:"
#: src/gtk.c:273
msgid "Output sample size (bits):"
msgstr "Dimensione campione d'output (in bit):"
#: src/gtk.c:277
msgid "Output channels:"
msgstr "Canali d'output:"
#: src/gtk.c:280
msgid "ISDN device:"
msgstr "Periferica ISDN:"
#: src/gtk.c:281
msgid "ISDN speed (samples):"
msgstr "Velocità ISDN (campioni):"
#: src/gtk.c:282
msgid "ISDN sample size (bits):"
msgstr "Dimensioni campione ISDN (in bit)):"
#: src/gtk.c:283
msgid "ISDN fragment size (bytes):"
msgstr "Dimensione frammento ISDN (in byte):"
#: src/gtk.c:295
msgid "ANT Info"
msgstr "Info ANT"
#: src/gtk.c:366
msgid "About ANT"
msgstr "A proposito di ANT"
#: src/gtk.c:382
#, c-format
msgid ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"This is an ISDN telephone application\n"
"written for GNU/Linux and ISDN4Linux for\n"
"communicating via a full duplex soundcard (or\n"
"multiple sound devices if you like) and an\n"
"audio capable ISDN4Linux ISDN device\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing list: ant-phone-devel@nongnu.org"
msgstr ""
"ANT (ANT Non è un Telefono) Versione %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"E' un'applicazione di telefonia\n"
"scritta per GNU/Linux e ISDN4Linux per\n"
"comunicare tramite una scheda audio full duplex\n"
"(o più schede audio se preferite) e una\n"
"scheda ISDN supportata da ISDN4Linux\n"
"capace di gestire l'audio.\n"
"\n"
"Contatto:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing List: ant-phone-devel@nongnu.org"
#: src/gtk.c:420
msgid "ANT License"
msgstr "Licenza di ANT"
#: src/gtk.c:421
msgid ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
msgstr ""
"ANT (ANT Non è un Telefono)\n"
"Copyright © 2002, 2003 Roland Stigge\n"
"\n"
"Questo programma è libero; potete ridistribuirlo secondo i termini della\n"
"licenza GNU General Public License, come pubblicata dalla Free Software\n"
"Foundation, sia la versione 2 della licenza, o.\n"
"(se preferite) qualsiasi versione successiva.\n"
"\n"
"Questo programma viene distribuito con la speranza che possa essere\n"
"utile, ma SENZA ALCUNA GARANZIA, sia per ragioni COMMERCIALI che per\n"
"SOPPERIRE AD UN BISOGNO PARTICOLARE. Si veda la GNU General Public License\n"
"per maggiori dettagli.\n"
"\n"
"Dovreste aver ricevuto una copia della GNU General Public License insieme\n"
"a questo programma; in caso contrario, scrivete alla Free Software\n"
"Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
#: src/gtk.c:454
msgid "/Phon_e"
msgstr "/_Telefono"
#: src/gtk.c:455
msgid "/Phone/_Info Window"
msgstr "/Telefono/_Finestra Informazioni"
#: src/gtk.c:456 src/gtk.c:504
msgid "/Phone/_Line Level Check"
msgstr "/Telefono/_Verifica segnale della linea"
#: src/gtk.c:458
msgid "/Phone/"
msgstr "/Telefono/"
#: src/gtk.c:459
msgid "/Phone/_Quit"
msgstr "/Telefono/_Esci"
#: src/gtk.c:461
msgid "/_View"
msgstr "/_Visualizza"
#: src/gtk.c:462 src/gtk.c:492
msgid "/View/_Caller ID Monitor"
msgstr "/Visualizza/_Monitor ID chiamante"
#: src/gtk.c:464 src/gtk.c:495
msgid "/View/_Line Level Meters"
msgstr "/Visualizza/_Livello della linea"
#: src/gtk.c:466 src/gtk.c:498
msgid "/View/Control _Pad"
msgstr "/Visionner/_Pannello di controllo"
#: src/gtk.c:468
msgid "/_Options"
msgstr "/_Opzioni"
#: src/gtk.c:469 src/gtk.c:501
msgid "/Options/_Settings"
msgstr "/Optioni/_Configurazioni"
#: src/gtk.c:471
msgid "/_Help"
msgstr "/_Aiuto"
#: src/gtk.c:472
msgid "/Help/_About"
msgstr "/Aiuto/_About"
#: src/gtk.c:473
msgid "/Help/_License"
msgstr "/Aiut/_Licenza"
#: src/gtk.c:551 src/gtksettings.c:431 src/session.c:68
msgid "Dialing"
msgstr "Chiamata in corso"
#: src/gtk.c:783 src/gtk.c:784
msgid "MUTED"
msgstr "MUTO"
#: src/gtksettings.c:230
msgid "Bad isdn/sound device settings, please try again."
msgstr "Configurazione periferica isdn/audio non valida, prego riprovare."
#: src/gtksettings.c:293
msgid "ANT Settings"
msgstr "Configurazione ANT"
#: src/gtksettings.c:306
msgid "Application"
msgstr "Applicazione"
#: src/gtksettings.c:308
msgid "Options"
msgstr "Opzioni"
#: src/gtksettings.c:320
msgid "Save options on exit"
msgstr "Salva le opzioni all'uscita"
#: src/gtksettings.c:327
msgid "Popup main window on incoming call"
msgstr "Popup finestra principale su chiamate in entrata"
#: src/gtksettings.c:333
msgid "Execute on incoming call:"
msgstr "Éseguire su chiamate in entrata"
#: src/gtksettings.c:344
msgid "Recording Format"
msgstr "Format di registrazione"
#: src/gtksettings.c:354
msgid "Microsoft WAV, uLaw"
msgstr "Microsoft WAV, uLaw"
#: src/gtksettings.c:364
msgid "Microsoft WAV, 16-bit signed"
msgstr "Microsoft WAV, 16 bit con segno"
#: src/gtksettings.c:374
msgid "Apple/SGI AIFF, uLaw"
msgstr "Apple/SGI AIFF, uLaw"
#: src/gtksettings.c:384
msgid "Apple/SGI AIFF, 16-bit signed"
msgstr "Apple/SGI AIFF, 16 bits con segno"
#: src/gtksettings.c:397
msgid "Phone"
msgstr "Telefono"
#: src/gtksettings.c:399
msgid "ISDN"
msgstr "ISDN"
#: src/gtksettings.c:411
msgid "Identifying MSN:"
msgstr "MSN identificativo:"
#: src/gtksettings.c:421
msgid "Listen to MSNs:"
msgstr "Ascolta i MSN:"
#: src/gtksettings.c:443
msgid "Dial history size:"
msgstr "Dimensioni file cronologia:"
#: src/gtksettings.c:467
msgid "Maximum CID rows:"
msgstr "Massimo numero di righe CID:"
#: src/gtksettings.c:475 src/gtksettings.c:503
msgid "[no limit]"
msgstr "[nessun limite]"
#: src/gtksettings.c:484
msgid "Read isdnlog data on startup"
msgstr "Leggere i dati di isdnlog all'avvio"
#: src/gtksettings.c:491
msgid "Maximum days to read from isdnlog:"
msgstr "Numero massimo di giorni da leggere su isdnlog:"
#: src/gtksettings.c:520
msgid "Sound Devices"
msgstr "Periferica Audio"
#: src/gtksettings.c:522
msgid "OSS"
msgstr "OSS"
#: src/gtksettings.c:534
msgid "Input sound device:"
msgstr "Periferica d'input audio:"
#: src/gtksettings.c:546
msgid "Output sound device:"
msgstr "Periferica d'output audio:"
#: src/gtksettings.c:559
msgid "Release unused devices"
msgstr "Liberare periferiche inutilizzate"
#: src/gtksettings.c:609
msgid "Save"
msgstr "Salva"
#: src/llcheck.c:371
msgid "Line Level Check"
msgstr "Verifica livello di linea"
#: src/llcheck.c:383
msgid ""
"Please check the line input level\n"
"and adjust it using your favorite\n"
"mixer application.\n"
"You can also play a sound\n"
"to test the sound output."
msgstr ""
"Prego controlla il livello della linea d'entrata\n"
"e modificatela usando il vostro mixer preferito.\n"
"Potete anche utilizzare un file audio per testare\n"
"l'uscita audio."
#: src/llcheck.c:405
msgid "Play sound"
msgstr "Play"
#: src/session.c:65
msgid "Ready"
msgstr "Pronto"
#: src/session.c:65
msgid "Dial"
msgstr "Componi"
#: src/session.c:65 src/session.c:69 src/session.c:70
msgid "Hang up"
msgstr "Aggancia"
#: src/session.c:66 src/session.c:67
msgid "RING"
msgstr "SUONERIA"
#: src/session.c:66 src/session.c:67
msgid "Answer"
msgstr "Rispondi"
#: src/session.c:66 src/session.c:67
msgid "Reject"
msgstr "Rifiuta"
#: src/session.c:68 src/session.c:69 src/session.c:70 src/session.c:71
msgid "Pick up"
msgstr "Alza la cornetta"
#: src/session.c:69
msgid "B-Channel open"
msgstr "Canale B aperto"
#: src/session.c:70
msgid "Setup"
msgstr "Configurazione"
#: src/session.c:71
msgid "Playback"
msgstr "Playback"
#: src/session.c:71
msgid "Stop"
msgstr "Stop"
#: src/session.c:377
#, c-format
msgid "Preset %d"
msgstr "Preselezione %d"
#: src/session.c:699
msgid "(HW ERROR)"
msgstr "(ERRORE HARDWARE)"
#: src/session.c:1000
msgid "Audio OFF"
msgstr "Audio OFF"
#: src/session.c:1000
msgid "Audio ON"
msgstr "Audio ON"
#: src/session.c:1097
msgid "(BUSY)"
msgstr "(OCCUPATO)"
#: src/session.c:1103
msgid "(TIMEOUT)"
msgstr "(TEMPO SCADUTO)"
#: src/session.c:1139
msgid "(RUNG)"
msgstr "(HA SUONATO)"
#: src/session.c:1381
msgid "(ABORTED)"
msgstr "(ANNULLATO)"
#: src/session.c:1389
msgid "(REJECTED)"
msgstr "(RIFIUTATO)"

663
po/nl.po Normal file
View File

@ -0,0 +1,663 @@
# Dutch translation of ant-phone.
# Copyright (C) 2003 Free Software Foundation, Inc.
# This file is distributed under the same license as the ant-phone package.
# Elros Cyriatan <cyriatan@fastmail.fm>, 2003.
#
msgid ""
msgstr ""
"Project-Id-Version: ant-phone 0.1.4\n"
"Report-Msgid-Bugs-To: stigge@antcom.de\n"
"POT-Creation-Date: 2004-04-03 18:51+0200\n"
"PO-Revision-Date: 2003-10-19 21:54+0100\n"
"Last-Translator: Elros Cyriatan <cyriatan@fastmail.fm>\n"
"Language-Team: Dutch <vertaling@nl.linux.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/ant-phone.c:170
#, c-format
msgid ""
"Usage: %s [OPTION...]\n"
"\n"
"Options:\n"
" -h, --help Show this help message\n"
" -v, --version Print version information\n"
" -r, --cleanup Remove stale socket file (left by accident by\n"
" previous run)\n"
" -d, --debug[=level] Print additional runtime debugging data to stdout\n"
" level = 1..2\n"
" -i, --soundin=DEVICE OSS compatible device for input (recording),\n"
" default: /dev/dsp\n"
" -o, --soundout=DEVICE OSS compatible device for output (playback),\n"
" default: /dev/dsp\n"
" -m, --msn=MSN identifying MSN (for outgoing calls), 0 for "
"master\n"
" MSN of this termination/port\n"
" default: 0\n"
" -l, --msns=MSNS MSNs to listen on, semicolon-separated list or "
"'*'\n"
" default: *\n"
" -c, --call=NUMBER Call specified number\n"
"\n"
"Note: If arguments of --soundin and --soundout are equal, a full duplex\n"
" sound device is needed.\n"
msgstr ""
"Gebruik: %s [OPTIE...]\n"
"\n"
"Opties:\n"
" -h, --help Dit hulpbericht weergeven\n"
" -v, --version Versie informatie weergeven\n"
" -r, --cleanup Per ongeluk (van vorige sessie) overgebleven\n"
" socket-bestand verwijderen\n"
" -d, --debug[=niveau] Extra runtime debug gegevens naar stdout zenden\n"
" niveau = 1..2\n"
" -i, --soundin=APPARAAT OSS-compatibel apparaat voor invoer (opname),\n"
" standaard: /dev/dsp\n"
" -o, --soundout=APPARAAT OSS-compatibel apparaat voor uitvoer (afspelen),\n"
" standaard: /dev/dsp\n"
" -m, --msn=MSN identificerende MSN (voor uitgaande gesprekken), 0 "
"voor hoofd\n"
" MSN van deze afsluiting/poort\n"
" standaard: 0\n"
" -l, --msns=MSNS MSNs om naar te luisteren, punt-komma gescheiden "
"lijst of '*'\n"
" standaard: *\n"
" -c, --call=NUMMER Opgegeven nummer bellen\n"
"\n"
"Let op: als argumenten van --soundin en --soundout gelijk zijn, is een full "
"duplex\n"
" geluidsapparaat nodig.\n"
#: src/ant-phone.c:221
#, c-format
msgid "Calling %s... "
msgstr "Bezig met bellen %s..."
#: src/ant-phone.c:225
#, c-format
msgid "successful.\n"
msgstr "succesvol.\n"
#: src/callerid.c:131
msgid "Delete Entry"
msgstr "Ingang verwijderen"
#: src/callerid.c:143
msgid ""
"Are you sure you want to\n"
"delete this entry?"
msgstr ""
"Weet u zeker dat u deze\n"
"ingang wilt verwijderen?"
#: src/callerid.c:148
msgid "Delete recording"
msgstr "Opname verwijderen"
#: src/callerid.c:266
#, c-format
msgid "Enter the base filename for %s file"
msgstr "Geef de basis-bestandsnaam voor %s bestand"
#: src/callerid.c:312
msgid "Do you really want to delete this recording?"
msgstr "Wilt u deze opname echt verwijderen?"
#: src/callerid.c:336 src/callerid.c:362
msgid "/_Playback"
msgstr "/_Afspelen"
#: src/callerid.c:337 src/callerid.c:366
msgid "/_Save as..."
msgstr "/_Opslaan als..."
#: src/callerid.c:338 src/callerid.c:370
msgid "/Delete _Recording"
msgstr "/_Opname verwijderen"
#: src/callerid.c:340 src/callerid.c:374
msgid "/_Delete Row"
msgstr "/_Rij verwijderen"
#: src/callerid.c:423 src/gtksettings.c:455
msgid "Caller ID"
msgstr "Beller ID"
#: src/callerid.c:426
msgid "Date/Time"
msgstr "Datum/Tijd"
#: src/callerid.c:427
msgid "Type"
msgstr "Soort"
#: src/callerid.c:428
msgid "From"
msgstr "Van"
#: src/callerid.c:429
msgid "To"
msgstr "Naar"
#: src/callerid.c:430
msgid "Duration"
msgstr "Lengte"
#: src/callerid.c:759
msgid "(UNKNOWN)"
msgstr "(ONBEKEND)"
#: src/callerid.c:828
#, c-format
msgid "ANT: %d unanswered"
msgstr "ANT: %d niet-beantwoord"
#: src/controlpad.c:101
#, c-format
msgid "Preset %c"
msgstr "Voorkeuze %c"
#: src/controlpad.c:108
#, c-format
msgid "Please input new preset data for button %c:"
msgstr "Geef a.u.b. nieuwe voorkeuze gegevens voor knop %c:"
#: src/controlpad.c:121
msgid "Name:"
msgstr "Naam:"
#: src/controlpad.c:124 src/gtk.c:561
msgid "Number:"
msgstr "Nummer:"
#: src/controlpad.c:144 src/gtk.c:212 src/gtk.c:331 src/gtk.c:408
#: src/gtksettings.c:571 src/llcheck.c:422
msgid "OK"
msgstr "OK"
#: src/controlpad.c:157 src/gtksettings.c:616 src/session.c:68
msgid "Cancel"
msgstr "Annuleren"
#: src/controlpad.c:315
msgid "Backspace"
msgstr "Backspace"
#: src/controlpad.c:315
msgid "Preset 1"
msgstr "Voorkeuze 1"
#: src/controlpad.c:316
msgid "Clear Number"
msgstr "Nummer wissen"
#: src/controlpad.c:316
msgid "Preset 2"
msgstr "Voorkeuze 2"
#: src/controlpad.c:317
msgid "Redial"
msgstr "Opnieuw bellen"
#: src/controlpad.c:317
msgid "Preset 3"
msgstr "Voorkeuze 3"
#: src/controlpad.c:318
msgid "Mute Microphone"
msgstr "Microfoon uit"
#: src/controlpad.c:318
msgid "Preset 4"
msgstr "Voorkeuze 4"
#: src/controlpad.c:351
msgid "Control"
msgstr "Bediening"
#: src/controlpad.c:423
msgid "Recording"
msgstr "Opname"
#: src/controlpad.c:434
msgid "Record to file"
msgstr "Opnemen naar bestand"
#: src/controlpad.c:445
msgid "Record local channel"
msgstr "Lokaal kanaal opnemen"
#: src/controlpad.c:456
msgid "Record remote channel"
msgstr "Kanaal op afstand opnemen"
#: src/gtk.c:230 src/gtksettings.c:229
msgid "ANT Note"
msgstr "ANT Bericht"
#: src/gtk.c:231
msgid ""
"Can't open audio device.\n"
"Please stop other applications using\n"
"the audio device(s) or check your\n"
"device settings and try again."
msgstr ""
"Kan geluidsapparaat niet openen.\n"
"Stop a.u.b. andere toepassingen die\n"
"het/de geluidsapparaat(en) gebruik(en)\n"
"of controleer uw apparaatinstellingen,\n"
"en probeer het opnieuw."
#: src/gtk.c:260
msgid "Sound input device:"
msgstr "Geluidsapparaat invoer:"
#: src/gtk.c:261
msgid "Input speed:"
msgstr "Invoersnelheid:"
#: src/gtk.c:261 src/gtk.c:264 src/gtk.c:265 src/gtk.c:267 src/gtk.c:271
#: src/gtk.c:274 src/gtk.c:275 src/gtk.c:277
msgid "[inactive]"
msgstr "[inactief]"
#: src/gtk.c:263
msgid "Input sample size (bits):"
msgstr "Invoer monstergrootte (bits):"
#: src/gtk.c:265 src/gtk.c:275
msgid "Input fragment size (samples):"
msgstr "Invoer fragmentgrootte (monsters):"
#: src/gtk.c:267
msgid "Input channels:"
msgstr "Invoerkanalen:"
#: src/gtk.c:270
msgid "Sound output device:"
msgstr "Geluidsapparaat uitvoer:"
#: src/gtk.c:271
msgid "Output speed:"
msgstr "Uitvoersnelheid:"
#: src/gtk.c:273
msgid "Output sample size (bits):"
msgstr "Uitvoer monstergrootte (bits):"
#: src/gtk.c:277
msgid "Output channels:"
msgstr "Uitvoerkanalen:"
#: src/gtk.c:280
msgid "ISDN device:"
msgstr "ISDN-apparaat:"
#: src/gtk.c:281
msgid "ISDN speed (samples):"
msgstr "ISDN snelheid (monsters):"
#: src/gtk.c:282
msgid "ISDN sample size (bits):"
msgstr "ISDN monstergrootte (bits):"
#: src/gtk.c:283
msgid "ISDN fragment size (bytes):"
msgstr "ISDN fragmentgrootte (bytes):"
#: src/gtk.c:295
msgid "ANT Info"
msgstr "ANT Info"
#: src/gtk.c:366
msgid "About ANT"
msgstr "Over ANT"
#: src/gtk.c:382
#, c-format
msgid ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"This is an ISDN telephone application\n"
"written for GNU/Linux and ISDN4Linux for\n"
"communicating via a full duplex soundcard (or\n"
"multiple sound devices if you like) and an\n"
"audio capable ISDN4Linux ISDN device\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing list: ant-phone-devel@nongnu.org"
msgstr ""
"ANT (ANT is Niet een Telefoon) Versie %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"Dit is een ISDN telefoon toepassing\n"
"geschreven voor GNU/Linux en ISDN4Linux om\n"
"te communiceren via een full duplex geluidskaart\n"
"(of meerdere geluidsapparaten als u dat wilt) en\n"
"een ISDN4Linux ISDN-apparaat dat geluid\n"
"ondersteunt.\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"E-mail lijst: ant-phone-devel@nongnu.org"
#: src/gtk.c:420
msgid "ANT License"
msgstr "ANT Licentie"
#: src/gtk.c:421
msgid ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
msgstr ""
"ANT (ANT is Niet een Telefoon)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
#: src/gtk.c:454
msgid "/Phon_e"
msgstr "/_Telefoon"
#: src/gtk.c:455
msgid "/Phone/_Info Window"
msgstr "/Telefoon/_Info"
#: src/gtk.c:456 src/gtk.c:504
msgid "/Phone/_Line Level Check"
msgstr "/Telefoon/Lijnniveau _controle"
#: src/gtk.c:458
msgid "/Phone/"
msgstr "/Telefoon/"
#: src/gtk.c:459
msgid "/Phone/_Quit"
msgstr "/Telefoon/_Afsluiten"
#: src/gtk.c:461
msgid "/_View"
msgstr "/B_eeld"
#: src/gtk.c:462 src/gtk.c:492
msgid "/View/_Caller ID Monitor"
msgstr "/Beeld/_Beller ID lijst"
#: src/gtk.c:464 src/gtk.c:495
msgid "/View/_Line Level Meters"
msgstr "/Beeld/_Lijnniveau meters"
#: src/gtk.c:466 src/gtk.c:498
msgid "/View/Control _Pad"
msgstr "/Beeld/Bedienings_paneel"
#: src/gtk.c:468
msgid "/_Options"
msgstr "/_Opties"
#: src/gtk.c:469 src/gtk.c:501
msgid "/Options/_Settings"
msgstr "/Opties/_Instellingen"
#: src/gtk.c:471
msgid "/_Help"
msgstr "/_Hulp"
#: src/gtk.c:472
msgid "/Help/_About"
msgstr "/Hulp/_Info"
#: src/gtk.c:473
msgid "/Help/_License"
msgstr "/Help/_Licentie"
#: src/gtk.c:551 src/gtksettings.c:431 src/session.c:68
msgid "Dialing"
msgstr "Bezig met bellen"
#: src/gtk.c:783 src/gtk.c:784
msgid "MUTED"
msgstr "GELUID UIT"
#: src/gtksettings.c:230
msgid "Bad isdn/sound device settings, please try again."
msgstr ""
"Slechte ISDN/geluid apparaat instellingen, probeer alstublieft opnieuw."
#: src/gtksettings.c:293
msgid "ANT Settings"
msgstr "ANT Instellingen"
#: src/gtksettings.c:306
msgid "Application"
msgstr "Toepassing"
#: src/gtksettings.c:308
msgid "Options"
msgstr "Opties"
#: src/gtksettings.c:320
msgid "Save options on exit"
msgstr "Opties opslaan bij afsluiten"
#: src/gtksettings.c:327
msgid "Popup main window on incoming call"
msgstr "Venster openen bij inkomend gesprek"
#: src/gtksettings.c:333
msgid "Execute on incoming call:"
msgstr "Uitvoeren bij inkomend gesprek:"
#: src/gtksettings.c:344
msgid "Recording Format"
msgstr "Opname formaat"
#: src/gtksettings.c:354
msgid "Microsoft WAV, uLaw"
msgstr "Microsoft WAV, uLaw"
#: src/gtksettings.c:364
msgid "Microsoft WAV, 16-bit signed"
msgstr "Microsoft WAV, 16-bit met teken"
#: src/gtksettings.c:374
msgid "Apple/SGI AIFF, uLaw"
msgstr "Apple/SGI AIFF, uLaw"
#: src/gtksettings.c:384
msgid "Apple/SGI AIFF, 16-bit signed"
msgstr "Apple/SGI AIFF, 16-bit met teken"
#: src/gtksettings.c:397
msgid "Phone"
msgstr "Telefoon"
#: src/gtksettings.c:399
msgid "ISDN"
msgstr "ISDN"
#: src/gtksettings.c:411
msgid "Identifying MSN:"
msgstr "Identificerende MSN:"
#: src/gtksettings.c:421
msgid "Listen to MSNs:"
msgstr "Luisteren-naar MSNs:"
#: src/gtksettings.c:443
msgid "Dial history size:"
msgstr "Belgeschiedenis grootte:"
#: src/gtksettings.c:467
msgid "Maximum CID rows:"
msgstr "Maximaal aantal CID rijen:"
#: src/gtksettings.c:475 src/gtksettings.c:503
msgid "[no limit]"
msgstr "[geen grens]"
#: src/gtksettings.c:484
msgid "Read isdnlog data on startup"
msgstr "Gegevens isdnlog lezen bij opstarten"
#: src/gtksettings.c:491
msgid "Maximum days to read from isdnlog:"
msgstr "Maximaal aantal dagen om te lezen van isdnlog:"
#: src/gtksettings.c:520
msgid "Sound Devices"
msgstr "Geluidsapparaten"
#: src/gtksettings.c:522
msgid "OSS"
msgstr "OSS"
#: src/gtksettings.c:534
msgid "Input sound device:"
msgstr "Geluidsapparaat invoer:"
#: src/gtksettings.c:546
msgid "Output sound device:"
msgstr "Geluidsapparaat uitvoer:"
#: src/gtksettings.c:559
msgid "Release unused devices"
msgstr "Ongebruikte apparaten vrijgeven"
#: src/gtksettings.c:609
msgid "Save"
msgstr "Opslaan"
#: src/llcheck.c:371
msgid "Line Level Check"
msgstr "Lijnniveau controle"
#: src/llcheck.c:383
msgid ""
"Please check the line input level\n"
"and adjust it using your favorite\n"
"mixer application.\n"
"You can also play a sound\n"
"to test the sound output."
msgstr ""
"Controleer alstublieft het lijn invoer\n"
"niveau en pas het aan met de\n"
"volumeregeling toepassing.\n"
"U kunt ook een geluid afspelen om\n"
"geluidsuitvoer te testen."
#: src/llcheck.c:405
msgid "Play sound"
msgstr "Geluid afspelen"
#: src/session.c:65
msgid "Ready"
msgstr "Gereed"
#: src/session.c:65
msgid "Dial"
msgstr "Bellen"
#: src/session.c:65 src/session.c:69 src/session.c:70
msgid "Hang up"
msgstr "Ophangen"
#: src/session.c:66 src/session.c:67
msgid "RING"
msgstr "TELEFOON GAAT OVER"
#: src/session.c:66 src/session.c:67
msgid "Answer"
msgstr "Beantwoorden"
#: src/session.c:66 src/session.c:67
msgid "Reject"
msgstr "Verwerpen"
#: src/session.c:68 src/session.c:69 src/session.c:70 src/session.c:71
msgid "Pick up"
msgstr "Opnemen"
#: src/session.c:69
msgid "B-Channel open"
msgstr "B-kanaal open"
#: src/session.c:70
msgid "Setup"
msgstr "Configuratie"
#: src/session.c:71
msgid "Playback"
msgstr "Afspelen"
#: src/session.c:71
msgid "Stop"
msgstr "Stoppen"
#: src/session.c:377
#, c-format
msgid "Preset %d"
msgstr "Voorkeuze %d"
#: src/session.c:699
msgid "(HW ERROR)"
msgstr "(HW FOUT)"
#: src/session.c:1000
msgid "Audio OFF"
msgstr "Geluid UIT"
#: src/session.c:1000
msgid "Audio ON"
msgstr "Geluid AAN"
#: src/session.c:1097
msgid "(BUSY)"
msgstr "(BEZIG)"
#: src/session.c:1103
msgid "(TIMEOUT)"
msgstr "(TIME-OUT)"
#: src/session.c:1139
msgid "(RUNG)"
msgstr "(TELEFOON GING OVER)"
#: src/session.c:1381
msgid "(ABORTED)"
msgstr "(AFGEBROKEN)"
#: src/session.c:1389
msgid "(REJECTED)"
msgstr "(VERWORPEN)"

661
po/ro.po Normal file
View File

@ -0,0 +1,661 @@
# Mesajele în limba românã pentru pachetul ant-phone.
# Copyright (C) 2003 Free Software Foundation, Inc.
# Acest fi?ier este distribuit sub aceea?i licen?? ca pachetul ant-phone.
# Eugen Hoanca <eugenh@urban-grafx.ro>, 2003.
msgid ""
msgstr ""
"Project-Id-Version: ant-phone 0.1.4\n"
"Report-Msgid-Bugs-To: stigge@antcom.de\n"
"POT-Creation-Date: 2004-04-03 18:51+0200\n"
"PO-Revision-Date: 2003-08-18 08:26+0300\n"
"Last-Translator: Eugen Hoanca <eugenh@urban-grafx.ro>\n"
"Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-2\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/ant-phone.c:170
#, c-format
msgid ""
"Usage: %s [OPTION...]\n"
"\n"
"Options:\n"
" -h, --help Show this help message\n"
" -v, --version Print version information\n"
" -r, --cleanup Remove stale socket file (left by accident by\n"
" previous run)\n"
" -d, --debug[=level] Print additional runtime debugging data to stdout\n"
" level = 1..2\n"
" -i, --soundin=DEVICE OSS compatible device for input (recording),\n"
" default: /dev/dsp\n"
" -o, --soundout=DEVICE OSS compatible device for output (playback),\n"
" default: /dev/dsp\n"
" -m, --msn=MSN identifying MSN (for outgoing calls), 0 for "
"master\n"
" MSN of this termination/port\n"
" default: 0\n"
" -l, --msns=MSNS MSNs to listen on, semicolon-separated list or "
"'*'\n"
" default: *\n"
" -c, --call=NUMBER Call specified number\n"
"\n"
"Note: If arguments of --soundin and --soundout are equal, a full duplex\n"
" sound device is needed.\n"
msgstr ""
"Folosire: %s [OPÞIUNE...]\n"
"\n"
"Opþiuni:\n"
" -h, --help Afiºeazã acest mesaj de ajutor\n"
" -v, --version Afiºeazã informaþii despre versiune\n"
" -r, --cleanup ªterge fiºierul de socket blocat (lãsat accidental "
"de\n"
" o rulare precedentã)\n"
" -d, --debug[=nivel] Afiºeazã date suplimentare de debug la stdout\n"
" nivel = 1..2\n"
" -i, --soundin=DISPOZITIV dispozitiv compatibil OSS pentru intrare "
"(înregistrare),\n"
" implicit: /dev/dsp\n"
" -o, --soundout=DEVICE dispozitiv compatibil OSS pentru ieºire "
"(playback),\n"
" implicit: /dev/dsp\n"
" -m, --msn=MSN identificare MSN (pentru apeluri efectuate), 0 "
"pentru master\n"
" MSN al acestei terminaþi/port\n"
" implicit: 0\n"
" -l, --msns=MSNS MSNuri pe care sã se asculte, listã separatã prin "
"punct ºi virgulã sau '*'\n"
" implicit: *\n"
" -c, --call=NUMÃR Apeleazã numãrul specificat\n"
"\n"
"Notã: Dacã parametrii --soundin ºi --soundout sunt egali, va fi necesar un\n"
" dispozitiv de sunet full-duplex.\n"
#: src/ant-phone.c:221
#, c-format
msgid "Calling %s... "
msgstr "Apelare %s... "
#: src/ant-phone.c:225
#, c-format
msgid "successful.\n"
msgstr "succes.\n"
#: src/callerid.c:131
msgid "Delete Entry"
msgstr "ªterge Intrarea"
#: src/callerid.c:143
msgid ""
"Are you sure you want to\n"
"delete this entry?"
msgstr ""
"Sunteþi sigur cã vreþi sã ºtergeþi\n"
"aceastã intrare?"
#: src/callerid.c:148
msgid "Delete recording"
msgstr "ªterge înregistrare"
#: src/callerid.c:266
#, c-format
msgid "Enter the base filename for %s file"
msgstr "Introduceþi numele de fiºier de bazã pentru fiºierul %s"
#: src/callerid.c:312
msgid "Do you really want to delete this recording?"
msgstr "Chiar vreþi sã ºtergeþi aceastã înregistrare?"
#: src/callerid.c:336 src/callerid.c:362
msgid "/_Playback"
msgstr "/_Playback"
#: src/callerid.c:337 src/callerid.c:366
msgid "/_Save as..."
msgstr "/_Salvare ca..."
#: src/callerid.c:338 src/callerid.c:370
msgid "/Delete _Recording"
msgstr "/ªterge În_registrare"
#: src/callerid.c:340 src/callerid.c:374
msgid "/_Delete Row"
msgstr "/ªterge Rân_d"
#: src/callerid.c:423 src/gtksettings.c:455
msgid "Caller ID"
msgstr "ID Apelant(Caller ID)"
#: src/callerid.c:426
msgid "Date/Time"
msgstr "Datã/Orã"
#: src/callerid.c:427
msgid "Type"
msgstr "Tip"
#: src/callerid.c:428
msgid "From"
msgstr "De la"
#: src/callerid.c:429
msgid "To"
msgstr "Cãtre"
#: src/callerid.c:430
msgid "Duration"
msgstr "durata"
#: src/callerid.c:759
msgid "(UNKNOWN)"
msgstr "(NECUNOSCUT)"
#: src/callerid.c:828
#, c-format
msgid "ANT: %d unanswered"
msgstr "ANT: %d fãrã rãspuns"
#: src/controlpad.c:101
#, c-format
msgid "Preset %c"
msgstr "Preset %c"
#: src/controlpad.c:108
#, c-format
msgid "Please input new preset data for button %c:"
msgstr "Vã rugãm introduceþi date preset noi pentru butonul %c:"
#: src/controlpad.c:121
msgid "Name:"
msgstr "Nume:"
#: src/controlpad.c:124 src/gtk.c:561
msgid "Number:"
msgstr "Numãr:"
#: src/controlpad.c:144 src/gtk.c:212 src/gtk.c:331 src/gtk.c:408
#: src/gtksettings.c:571 src/llcheck.c:422
msgid "OK"
msgstr "OK"
#: src/controlpad.c:157 src/gtksettings.c:616 src/session.c:68
msgid "Cancel"
msgstr "Renunþare"
#: src/controlpad.c:315
msgid "Backspace"
msgstr "Backspace"
#: src/controlpad.c:315
msgid "Preset 1"
msgstr "Preset 1"
#: src/controlpad.c:316
msgid "Clear Number"
msgstr "ªterge Numãr"
#: src/controlpad.c:316
msgid "Preset 2"
msgstr "Preset 2"
#: src/controlpad.c:317
msgid "Redial"
msgstr "Formeazã din nou"
#: src/controlpad.c:317
msgid "Preset 3"
msgstr "Preset 3"
#: src/controlpad.c:318
msgid "Mute Microphone"
msgstr "Inhibã Microfon"
#: src/controlpad.c:318
msgid "Preset 4"
msgstr "Preset 4"
#: src/controlpad.c:351
msgid "Control"
msgstr "Control"
#: src/controlpad.c:423
msgid "Recording"
msgstr "Înregistrare"
#: src/controlpad.c:434
msgid "Record to file"
msgstr "Înregistreazã în fiºier"
#: src/controlpad.c:445
msgid "Record local channel"
msgstr "Înregistreazã canal local"
#: src/controlpad.c:456
msgid "Record remote channel"
msgstr "Înregistreazã canalul remote"
#: src/gtk.c:230 src/gtksettings.c:229
msgid "ANT Note"
msgstr "ANT Notã"
#: src/gtk.c:231
msgid ""
"Can't open audio device.\n"
"Please stop other applications using\n"
"the audio device(s) or check your\n"
"device settings and try again."
msgstr ""
"Nu se poate accesa dispozitivul audio.\n"
"Vã rugãm opriþi alte aplicaþii care folosesc\n"
"dispozitivul(ele) audio sau verifcaþi\n"
"setãrile dispozitivului ºi încercaþi din nou."
#: src/gtk.c:260
msgid "Sound input device:"
msgstr "Dispozitiv intrare de sunet:"
#: src/gtk.c:261
msgid "Input speed:"
msgstr "Vitezã de intrare(input):"
#: src/gtk.c:261 src/gtk.c:264 src/gtk.c:265 src/gtk.c:267 src/gtk.c:271
#: src/gtk.c:274 src/gtk.c:275 src/gtk.c:277
msgid "[inactive]"
msgstr "[inactiv]"
#: src/gtk.c:263
msgid "Input sample size (bits):"
msgstr "Mãrime de intrare (biþi):"
#: src/gtk.c:265 src/gtk.c:275
msgid "Input fragment size (samples):"
msgstr "Mãrime intrare fragment (exemple):"
#: src/gtk.c:267
msgid "Input channels:"
msgstr "Canale de intrare:"
#: src/gtk.c:270
msgid "Sound output device:"
msgstr "Dispozitiv ieºire de sunet:"
#: src/gtk.c:271
msgid "Output speed:"
msgstr "Vitezã de ieºire:"
#: src/gtk.c:273
msgid "Output sample size (bits):"
msgstr "Mãrime de ieºire (biþi):"
#: src/gtk.c:277
msgid "Output channels:"
msgstr "Canale de ieºire:"
#: src/gtk.c:280
msgid "ISDN device:"
msgstr "Dispozitiv ISDN:"
#: src/gtk.c:281
msgid "ISDN speed (samples):"
msgstr "Vitezã ISDN (exemple):"
#: src/gtk.c:282
msgid "ISDN sample size (bits):"
msgstr "Mãrime exemplu ISDN (biþi)"
#: src/gtk.c:283
msgid "ISDN fragment size (bytes):"
msgstr "Mãrime fragment ISDN (octeþi):"
#: src/gtk.c:295
msgid "ANT Info"
msgstr "ANT Info"
#: src/gtk.c:366
msgid "About ANT"
msgstr "Despre ANT"
#: src/gtk.c:382
#, c-format
msgid ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"This is an ISDN telephone application\n"
"written for GNU/Linux and ISDN4Linux for\n"
"communicating via a full duplex soundcard (or\n"
"multiple sound devices if you like) and an\n"
"audio capable ISDN4Linux ISDN device\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing list: ant-phone-devel@nongnu.org"
msgstr ""
"ANT (ANT Nu este un Telefon) Versiunea %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"Aceasta este o aplicaþie de telefon ISDN\n"
"scrisã pentru GNU/Linux ºi ISDN4Linux pentru\n"
"comunicarea printr-o placã de sunet full-duplex (sau\n"
"mai multe plãci de sunet dacã vreþi) ºi un\n"
"dispozitivISDN capabil de sunet ISDN4Linux\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Listã de discuþii: ant-phone-devel@nongnu.org"
#: src/gtk.c:420
msgid "ANT License"
msgstr "ANT Licenþã"
#: src/gtk.c:421
msgid ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
msgstr ""
"ANT (ANT Nu este un Telefon)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"Acest program este software liber; puteþi sã-l redistribuiþi ºi/"
"saumodificaþi sub termenii Licenþei Publice Generale GNU\n"
"publicatã de Free Software Foundation; fie versiunea 2\n"
"a Licenþei, fie (opþiunea dumneavoastrã) orice versiune ulterioarã\n"
"\n"
"Acest program este distribuit în speranþa cã va fi folositor,\n"
"dar FÃRÃ NICI O GARANÞIE; chiar fãrã garanþia sugeratã de\n"
"VANDABILITATE sau MODIFICARE ÎN SCOP PERSONAL. Citiþi\n"
"Licenþa Publicã Generalã GNU pentru mai multe detalii.\n"
"\n"
"Ar fi trebui sã fi primit ºi o copie a Licenþei Publice Generale GNU \n"
"împreunã cu acest progra,; dacã nu, scrieþi la Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
#: src/gtk.c:454
msgid "/Phon_e"
msgstr "/T_elefon"
#: src/gtk.c:455
msgid "/Phone/_Info Window"
msgstr "/Telefon/Fereastrã _Info"
#: src/gtk.c:456 src/gtk.c:504
msgid "/Phone/_Line Level Check"
msgstr "/Phone/Verificare nivel _linie"
#: src/gtk.c:458
msgid "/Phone/"
msgstr "/Telefon/"
#: src/gtk.c:459
msgid "/Phone/_Quit"
msgstr "/Telefon/Ieºire(_Quit)"
#: src/gtk.c:461
msgid "/_View"
msgstr "/_Vizualizare"
#: src/gtk.c:462 src/gtk.c:492
msgid "/View/_Caller ID Monitor"
msgstr "/Vizualizare/Monitor_Caller ID"
#: src/gtk.c:464 src/gtk.c:495
msgid "/View/_Line Level Meters"
msgstr "/Vizualizare/Monitoare Nivel _Linie"
#: src/gtk.c:466 src/gtk.c:498
msgid "/View/Control _Pad"
msgstr "/Vizualizare/_Pad Control"
#: src/gtk.c:468
msgid "/_Options"
msgstr "/_Opþiuni"
#: src/gtk.c:469 src/gtk.c:501
msgid "/Options/_Settings"
msgstr "/Opþiuni/_Setãri"
#: src/gtk.c:471
msgid "/_Help"
msgstr "/Ajutor(_Help)"
#: src/gtk.c:472
msgid "/Help/_About"
msgstr "/Ajutor/Despre(_About)"
#: src/gtk.c:473
msgid "/Help/_License"
msgstr "/Ajutor/_Licenþã"
#: src/gtk.c:551 src/gtksettings.c:431 src/session.c:68
msgid "Dialing"
msgstr "Apelare"
#: src/gtk.c:783 src/gtk.c:784
msgid "MUTED"
msgstr "TRECUT PE MUTE"
#: src/gtksettings.c:230
msgid "Bad isdn/sound device settings, please try again."
msgstr "Setãri greºite isdn/sunet, încercaþi din nou."
#: src/gtksettings.c:293
msgid "ANT Settings"
msgstr "ANT Setãri"
#: src/gtksettings.c:306
msgid "Application"
msgstr "Aplicaþie"
#: src/gtksettings.c:308
msgid "Options"
msgstr "Optiuni"
#: src/gtksettings.c:320
msgid "Save options on exit"
msgstr "Salveazã opþiunile la ieºire"
#: src/gtksettings.c:327
msgid "Popup main window on incoming call"
msgstr "Scoate în evidenþã (popup) fereastra principalã când sunã telefonul"
#: src/gtksettings.c:333
msgid "Execute on incoming call:"
msgstr "Executã atunci când sunã telefonul:"
#: src/gtksettings.c:344
msgid "Recording Format"
msgstr "Format Înregistrare"
#: src/gtksettings.c:354
msgid "Microsoft WAV, uLaw"
msgstr "Microsoft WAV, uLaw"
#: src/gtksettings.c:364
msgid "Microsoft WAV, 16-bit signed"
msgstr "Microsoft WAV, 16-biþi cu semn (signed)"
#: src/gtksettings.c:374
msgid "Apple/SGI AIFF, uLaw"
msgstr "Apple/SGI AIFF, uLaw"
#: src/gtksettings.c:384
msgid "Apple/SGI AIFF, 16-bit signed"
msgstr "Apple/SGI AIFF, 16-biþi cu smen (signed)"
#: src/gtksettings.c:397
msgid "Phone"
msgstr "Telefon"
#: src/gtksettings.c:399
msgid "ISDN"
msgstr "ISDN"
#: src/gtksettings.c:411
msgid "Identifying MSN:"
msgstr "Indetificare MSN:"
#: src/gtksettings.c:421
msgid "Listen to MSNs:"
msgstr "Ascultare MSNuri:"
#: src/gtksettings.c:443
msgid "Dial history size:"
msgstr "Mãrime istoric apelãri:"
#: src/gtksettings.c:467
msgid "Maximum CID rows:"
msgstr "Maxim de rânduri CID:"
#: src/gtksettings.c:475 src/gtksettings.c:503
msgid "[no limit]"
msgstr "[nelimitat]"
#: src/gtksettings.c:484
msgid "Read isdnlog data on startup"
msgstr "Citeºte date isdnlog la început"
#: src/gtksettings.c:491
msgid "Maximum days to read from isdnlog:"
msgstr "Maximum de zile de citit din isdnlog:"
#: src/gtksettings.c:520
msgid "Sound Devices"
msgstr "Dispozitive de Sunet:"
#: src/gtksettings.c:522
msgid "OSS"
msgstr "OSS"
#: src/gtksettings.c:534
msgid "Input sound device:"
msgstr "Dispozitiv de intrare de sunet:"
#: src/gtksettings.c:546
msgid "Output sound device:"
msgstr "Dispozitiv de ieºire de sunet:"
#: src/gtksettings.c:559
msgid "Release unused devices"
msgstr "Elibereazã(release) dispozitivele nefolosite"
#: src/gtksettings.c:609
msgid "Save"
msgstr "Salveazã"
#: src/llcheck.c:371
msgid "Line Level Check"
msgstr "Verificare Nivel Linie"
#: src/llcheck.c:383
msgid ""
"Please check the line input level\n"
"and adjust it using your favorite\n"
"mixer application.\n"
"You can also play a sound\n"
"to test the sound output."
msgstr ""
"Verificaþi nivelul de intrare al liniei\n"
"ºi ajustaþi-l folosind aplicaþia\n"
"de mixer preferatã.\n"
"Puteþi de asemenea sã ascultaþi un sunet\n"
"pentru a testa ieºirea de sunet."
#: src/llcheck.c:405
msgid "Play sound"
msgstr "Ascultare sunet"
#: src/session.c:65
msgid "Ready"
msgstr "Pregãtit(ready)"
#: src/session.c:65
msgid "Dial"
msgstr "Apelare"
#: src/session.c:65 src/session.c:69 src/session.c:70
msgid "Hang up"
msgstr "Întrerupere(hang-up)"
#: src/session.c:66 src/session.c:67
msgid "RING"
msgstr "SUNÃ(RING)"
#: src/session.c:66 src/session.c:67
msgid "Answer"
msgstr "Rãspuns"
#: src/session.c:66 src/session.c:67
msgid "Reject"
msgstr "Refuzare"
#: src/session.c:68 src/session.c:69 src/session.c:70 src/session.c:71
msgid "Pick up"
msgstr "Ridicare receptor"
#: src/session.c:69
msgid "B-Channel open"
msgstr "Canalul B deschis"
#: src/session.c:70
msgid "Setup"
msgstr "Setup"
#: src/session.c:71
msgid "Playback"
msgstr "Playback"
#: src/session.c:71
msgid "Stop"
msgstr "Stop"
#: src/session.c:377
#, c-format
msgid "Preset %d"
msgstr "Preset %d"
#: src/session.c:699
msgid "(HW ERROR)"
msgstr "(EROARE HW)"
#: src/session.c:1000
msgid "Audio OFF"
msgstr "Audio DEZACTIVAT"
#: src/session.c:1000
msgid "Audio ON"
msgstr "Audio ACTIVAT"
#: src/session.c:1097
msgid "(BUSY)"
msgstr "(OCUPAT)"
#: src/session.c:1103
msgid "(TIMEOUT)"
msgstr "(TIMP EXPIRAT)"
#: src/session.c:1139
msgid "(RUNG)"
msgstr "(SUNAT)"
#: src/session.c:1381
msgid "(ABORTED)"
msgstr "(RENUNÞAT)"
#: src/session.c:1389
msgid "(REJECTED)"
msgstr "(REJFUZAT)"

668
po/sv.po Normal file
View File

@ -0,0 +1,668 @@
# Swedish translation of ant-phone.
# Copyright (C) 2005 Roland Stigge
# This file is distributed under the same license as the ant-phone package.
# Daniel Nylander <po@danielnylander.se>, 2005.
#
msgid ""
msgstr ""
"Project-Id-Version: ant-phone 0.1.4\n"
"Report-Msgid-Bugs-To: stigge@antcom.de\n"
"POT-Creation-Date: 2004-04-03 18:51+0200\n"
"PO-Revision-Date: 2006-01-06 21:08+0100\n"
"Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/ant-phone.c:170
#, c-format
msgid ""
"Usage: %s [OPTION...]\n"
"\n"
"Options:\n"
" -h, --help Show this help message\n"
" -v, --version Print version information\n"
" -r, --cleanup Remove stale socket file (left by accident by\n"
" previous run)\n"
" -d, --debug[=level] Print additional runtime debugging data to stdout\n"
" level = 1..2\n"
" -i, --soundin=DEVICE OSS compatible device for input (recording),\n"
" default: /dev/dsp\n"
" -o, --soundout=DEVICE OSS compatible device for output (playback),\n"
" default: /dev/dsp\n"
" -m, --msn=MSN identifying MSN (for outgoing calls), 0 for "
"master\n"
" MSN of this termination/port\n"
" default: 0\n"
" -l, --msns=MSNS MSNs to listen on, semicolon-separated list or "
"'*'\n"
" default: *\n"
" -c, --call=NUMBER Call specified number\n"
"\n"
"Note: If arguments of --soundin and --soundout are equal, a full duplex\n"
" sound device is needed.\n"
msgstr ""
"Användning: %s [FLAGGA...]\n"
"\n"
"Flaggor:\n"
" -h, --help Visar detta hjälpmeddelande\n"
" -v, --version Skriv ut versionsinformation\n"
" -r, --cleanup Ta bort hängda socketfiler (kvarlämnade av "
"misstag\n"
" från tidigare körning)\n"
" -d, --debug[=nivå] Skriv ut ytterligare körtidsdata för felsökning "
"till\n"
" standard ut nivå = 1..2\n"
" -i, --soundin=ENHET OSS-kompatibel enhet för indata (inspelning),\n"
" förval: /dev/dsp\n"
" -o, --soundout=ENHET OSS-kompatibel enhet för utdata (uppspelning),\n"
" förval: /dev/dsp\n"
" -m, --msn=MSN identifierar MSN (för utgående samtal), 0 för "
"master\n"
" MSN för denna ändpunkt/port\n"
" förval: 0\n"
" -l, --msns=MSNS MSN:er att lyssna på, lista separerad med "
"semikolon\n"
" eller \"*\"\n"
" förval: *\n"
" -c, --call=NUMMER Ring angivet nummer\n"
"\n"
"Notera: Om argumenten för --soundin och --soundout är samma behövs ett\n"
" ljudkort med stöd för full duplex.\n"
"Skicka synpunkter på översättningen till tp-sv@listor.tp-sv.se\n"
#: src/ant-phone.c:221
#, c-format
msgid "Calling %s... "
msgstr "Ringer %s..."
#: src/ant-phone.c:225
#, c-format
msgid "successful.\n"
msgstr "lyckades.\n"
#: src/callerid.c:131
msgid "Delete Entry"
msgstr "Ta bort post"
#: src/callerid.c:143
msgid ""
"Are you sure you want to\n"
"delete this entry?"
msgstr ""
"Är du säker att du vill\n"
"ta bort denna post?"
#: src/callerid.c:148
msgid "Delete recording"
msgstr "Ta bort inspelning"
#: src/callerid.c:266
#, c-format
msgid "Enter the base filename for %s file"
msgstr "Ange basfilnamnet för filen %s"
#: src/callerid.c:312
msgid "Do you really want to delete this recording?"
msgstr "Vill du verkligen ta bort denna inspelning?"
#: src/callerid.c:336 src/callerid.c:362
msgid "/_Playback"
msgstr "/U_ppspelning"
#: src/callerid.c:337 src/callerid.c:366
msgid "/_Save as..."
msgstr "/_Spara som..."
#: src/callerid.c:338 src/callerid.c:370
msgid "/Delete _Recording"
msgstr "/Ta bo_rt inspelning"
#: src/callerid.c:340 src/callerid.c:374
msgid "/_Delete Row"
msgstr "/Ta bort ra_d"
#: src/callerid.c:423 src/gtksettings.c:455
msgid "Caller ID"
msgstr "Nummerpresentation"
#: src/callerid.c:426
msgid "Date/Time"
msgstr "Datum/Tid"
#: src/callerid.c:427
msgid "Type"
msgstr "Typ"
#: src/callerid.c:428
msgid "From"
msgstr "Från"
#: src/callerid.c:429
msgid "To"
msgstr "Till"
#: src/callerid.c:430
msgid "Duration"
msgstr "Längd"
#: src/callerid.c:759
msgid "(UNKNOWN)"
msgstr "(OKÄND)"
#: src/callerid.c:828
#, c-format
msgid "ANT: %d unanswered"
msgstr "ANT: %d obesvarade"
#: src/controlpad.c:101
#, c-format
msgid "Preset %c"
msgstr "Förval %c"
#: src/controlpad.c:108
#, c-format
msgid "Please input new preset data for button %c:"
msgstr "Mata in ny förvalsdata för knapp %c:"
#: src/controlpad.c:121
msgid "Name:"
msgstr "Namn:"
#: src/controlpad.c:124 src/gtk.c:561
msgid "Number:"
msgstr "Nummer:"
#: src/controlpad.c:144 src/gtk.c:212 src/gtk.c:331 src/gtk.c:408
#: src/gtksettings.c:571 src/llcheck.c:422
msgid "OK"
msgstr "OK"
#: src/controlpad.c:157 src/gtksettings.c:616 src/session.c:68
msgid "Cancel"
msgstr "Avbryt"
#: src/controlpad.c:315
msgid "Backspace"
msgstr "Baksteg"
#: src/controlpad.c:315
msgid "Preset 1"
msgstr "Förval 1"
#: src/controlpad.c:316
msgid "Clear Number"
msgstr "Rensa nummer"
#: src/controlpad.c:316
msgid "Preset 2"
msgstr "Förval 2"
#: src/controlpad.c:317
msgid "Redial"
msgstr "Återuppring"
#: src/controlpad.c:317
msgid "Preset 3"
msgstr "Förval 3"
#: src/controlpad.c:318
msgid "Mute Microphone"
msgstr "Tyst mikrofon"
#: src/controlpad.c:318
msgid "Preset 4"
msgstr "Förval 4"
#: src/controlpad.c:351
msgid "Control"
msgstr "Kontrollera"
#: src/controlpad.c:423
msgid "Recording"
msgstr "Spelar in"
#: src/controlpad.c:434
msgid "Record to file"
msgstr "Spela in till fil"
#: src/controlpad.c:445
msgid "Record local channel"
msgstr "Spela in lokal kanal"
#: src/controlpad.c:456
msgid "Record remote channel"
msgstr "Spela in fjärrkanal"
#: src/gtk.c:230 src/gtksettings.c:229
msgid "ANT Note"
msgstr "ANT-notering"
#: src/gtk.c:231
msgid ""
"Can't open audio device.\n"
"Please stop other applications using\n"
"the audio device(s) or check your\n"
"device settings and try again."
msgstr ""
"Kan inte öppna ljudenhet.\n"
"Vänligen stoppa andra applikationer\n"
"som använder ljudenheten eller\n"
"kontrollera dina enhetsinställningar\n"
"och försök igen."
#: src/gtk.c:260
msgid "Sound input device:"
msgstr "Enhet för ljudindata:"
#: src/gtk.c:261
msgid "Input speed:"
msgstr "Hastighet för indata:"
#: src/gtk.c:261 src/gtk.c:264 src/gtk.c:265 src/gtk.c:267 src/gtk.c:271
#: src/gtk.c:274 src/gtk.c:275 src/gtk.c:277
msgid "[inactive]"
msgstr "[inaktiv]"
#: src/gtk.c:263
msgid "Input sample size (bits):"
msgstr "Samplingsstorlek för indata (bitar):"
#: src/gtk.c:265 src/gtk.c:275
msgid "Input fragment size (samples):"
msgstr "Fragmentstorlek för indata (sampling):"
#: src/gtk.c:267
msgid "Input channels:"
msgstr "Indatakanaler:"
#: src/gtk.c:270
msgid "Sound output device:"
msgstr "Enhet för ljudutdata:"
#: src/gtk.c:271
msgid "Output speed:"
msgstr "Utdatahastighet:"
#: src/gtk.c:273
msgid "Output sample size (bits):"
msgstr "Samplingsstorlek för utdata (bitar):"
#: src/gtk.c:277
msgid "Output channels:"
msgstr "Kanaler för utdata:"
#: src/gtk.c:280
msgid "ISDN device:"
msgstr "ISDN-enhet:"
#: src/gtk.c:281
msgid "ISDN speed (samples):"
msgstr "ISDN-hastighet (sampling):"
#: src/gtk.c:282
msgid "ISDN sample size (bits):"
msgstr "Samplingsstorlek för ISDN (bitar):"
#: src/gtk.c:283
msgid "ISDN fragment size (bytes):"
msgstr "Fragmentstorlek för ISDN (bytes):"
#: src/gtk.c:295
msgid "ANT Info"
msgstr "ANT-info"
#: src/gtk.c:366
msgid "About ANT"
msgstr "Om ANT"
#: src/gtk.c:382
#, c-format
msgid ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"This is an ISDN telephone application\n"
"written for GNU/Linux and ISDN4Linux for\n"
"communicating via a full duplex soundcard (or\n"
"multiple sound devices if you like) and an\n"
"audio capable ISDN4Linux ISDN device\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing list: ant-phone-devel@nongnu.org"
msgstr ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"Detta är en applikation för ISDN-telefoner\n"
"skriven för GNU/Linux och ISDN4Linux för\n"
"att kommunicera via ett ljudkort med full\n"
"duplex (eller multipla ljudenheter om du vill)\n"
"och en ISDN4Linux ISDN-enhet kapabel\n"
"för ljud.\n"
"Kontakt:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"E-postlista: ant-phone-devel@nongnu.org"
#: src/gtk.c:420
msgid "ANT License"
msgstr "ANT-licens"
#: src/gtk.c:421
msgid ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
msgstr ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"Följande text är en informell översättning som enbart tillhandahålls i\n"
"informativt syfte. För alla juridiska tolkningar gäller den engelska\n"
"originaltexten.\n"
"\n"
"Detta program är fri programvara. Du kan distribuera det och/eller\n"
"modifiera det under villkoren i GNU General Public License, publicerad\n"
"av Free Software Foundation, antingen version 2 eller (om du så vill)\n"
"någon senare version.\n"
"\n"
"Detta program distribueras i hopp om att det ska vara användbart,\n"
"men UTAN NÅGON SOM HELST GARANTI, även utan underförstådd garanti\n"
"om SÄLJBARHET eller LÄMPLIGHET FÖR NÅGOT SPECIELLT ÄNDAMÅL. Se GNU\n"
"General Public License för ytterligare information.\n"
"\n"
"Du bör ha fått en kopia av GNU General Public License tillsammans\n"
"med detta program. Om inte, skriv till Free Software Foundation,\n"
"Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
#: src/gtk.c:454
msgid "/Phon_e"
msgstr "/T_elefon"
#: src/gtk.c:455
msgid "/Phone/_Info Window"
msgstr "/Telefon/_Infofönster"
#: src/gtk.c:456 src/gtk.c:504
msgid "/Phone/_Line Level Check"
msgstr "/Telefon/_Linjenivåkontroll"
#: src/gtk.c:458
msgid "/Phone/"
msgstr "/Telefon/"
#: src/gtk.c:459
msgid "/Phone/_Quit"
msgstr "/Telefon/A_vsluta"
#: src/gtk.c:461
msgid "/_View"
msgstr "/_Visa"
#: src/gtk.c:462 src/gtk.c:492
msgid "/View/_Caller ID Monitor"
msgstr "/Visa/_Nummerpresentationsvisare"
#: src/gtk.c:464 src/gtk.c:495
msgid "/View/_Line Level Meters"
msgstr "/Visa/_Linjenivåmätare"
#: src/gtk.c:466 src/gtk.c:498
msgid "/View/Control _Pad"
msgstr "/Visa/Kontroll_panel"
#: src/gtk.c:468
msgid "/_Options"
msgstr "/Inställningar"
#: src/gtk.c:469 src/gtk.c:501
msgid "/Options/_Settings"
msgstr "/Inställningar/_Konfiguration"
#: src/gtk.c:471
msgid "/_Help"
msgstr "/_Hjälp"
#: src/gtk.c:472
msgid "/Help/_About"
msgstr "/Hjälp/Om"
#: src/gtk.c:473
msgid "/Help/_License"
msgstr "/Hjälp/_Licens"
#: src/gtk.c:551 src/gtksettings.c:431 src/session.c:68
msgid "Dialing"
msgstr "Ringer"
#: src/gtk.c:783 src/gtk.c:784
msgid "MUTED"
msgstr "TYST"
#: src/gtksettings.c:230
msgid "Bad isdn/sound device settings, please try again."
msgstr "Felaktiga inställningar för ISDN/ljudenhet, försök igen."
#: src/gtksettings.c:293
msgid "ANT Settings"
msgstr "ANT-inställningar"
#: src/gtksettings.c:306
msgid "Application"
msgstr "Applikation"
#: src/gtksettings.c:308
msgid "Options"
msgstr "Inställningar"
#: src/gtksettings.c:320
msgid "Save options on exit"
msgstr "Spara inställningar vid avslut"
#: src/gtksettings.c:327
msgid "Popup main window on incoming call"
msgstr "Visa huvudfönster vid inkommande samtal"
#: src/gtksettings.c:333
msgid "Execute on incoming call:"
msgstr "Kör vid inkommande samtal:"
#: src/gtksettings.c:344
msgid "Recording Format"
msgstr "Inspelningsformat"
#: src/gtksettings.c:354
msgid "Microsoft WAV, uLaw"
msgstr "Microsoft WAV, uLaw"
#: src/gtksettings.c:364
msgid "Microsoft WAV, 16-bit signed"
msgstr "Microsoft WAV, 16-bit signed"
#: src/gtksettings.c:374
msgid "Apple/SGI AIFF, uLaw"
msgstr "Apple/SGI AIFF, uLaw"
#: src/gtksettings.c:384
msgid "Apple/SGI AIFF, 16-bit signed"
msgstr "Apple/SGI AIFF, 16-bit signed"
#: src/gtksettings.c:397
msgid "Phone"
msgstr "Telefon"
#: src/gtksettings.c:399
msgid "ISDN"
msgstr "ISDN"
#: src/gtksettings.c:411
msgid "Identifying MSN:"
msgstr "Identifierar MSN:"
#: src/gtksettings.c:421
msgid "Listen to MSNs:"
msgstr "Lyssnar till MSN:"
#: src/gtksettings.c:443
msgid "Dial history size:"
msgstr "Storlek för samtalshistorik:"
#: src/gtksettings.c:467
msgid "Maximum CID rows:"
msgstr "Max rader för nummerpresentation:"
#: src/gtksettings.c:475 src/gtksettings.c:503
msgid "[no limit]"
msgstr "[ingen gräns]"
#: src/gtksettings.c:484
msgid "Read isdnlog data on startup"
msgstr "Läs isdnlog-data vid uppstart"
#: src/gtksettings.c:491
msgid "Maximum days to read from isdnlog:"
msgstr "Max antal dagar att läsa från isdnlog:"
#: src/gtksettings.c:520
msgid "Sound Devices"
msgstr "Ljudenheter"
#: src/gtksettings.c:522
msgid "OSS"
msgstr "OSS"
#: src/gtksettings.c:534
msgid "Input sound device:"
msgstr "Enhet för ljudindata:"
#: src/gtksettings.c:546
msgid "Output sound device:"
msgstr "Enhet för ljudutdata:"
#: src/gtksettings.c:559
msgid "Release unused devices"
msgstr "Släpp oanvända enheter"
#: src/gtksettings.c:609
msgid "Save"
msgstr "Spara"
#: src/llcheck.c:371
msgid "Line Level Check"
msgstr "Linjenivåkontroll"
#: src/llcheck.c:383
msgid ""
"Please check the line input level\n"
"and adjust it using your favorite\n"
"mixer application.\n"
"You can also play a sound\n"
"to test the sound output."
msgstr ""
"Vänligen kontrollera indatanivån på\n"
"linjen och justera den med din favorit\n"
"mixerapplikation.\n"
"Du kan också spela ett ljud för att\n"
"testa ljudutdatat."
#: src/llcheck.c:405
msgid "Play sound"
msgstr "Spela ljud"
#: src/session.c:65
msgid "Ready"
msgstr "Klar"
#: src/session.c:65
msgid "Dial"
msgstr "Ring"
#: src/session.c:65 src/session.c:69 src/session.c:70
msgid "Hang up"
msgstr "Lägg på"
#: src/session.c:66 src/session.c:67
msgid "RING"
msgstr "RING"
#: src/session.c:66 src/session.c:67
msgid "Answer"
msgstr "Svara"
#: src/session.c:66 src/session.c:67
msgid "Reject"
msgstr "Neka"
#: src/session.c:68 src/session.c:69 src/session.c:70 src/session.c:71
msgid "Pick up"
msgstr "Lyft"
#: src/session.c:69
msgid "B-Channel open"
msgstr "B-kanal öppen"
#: src/session.c:70
msgid "Setup"
msgstr "Ställ in"
#: src/session.c:71
msgid "Playback"
msgstr "Uppspelning"
#: src/session.c:71
msgid "Stop"
msgstr "Stopp"
#: src/session.c:377
#, c-format
msgid "Preset %d"
msgstr "Förval %d"
#: src/session.c:699
msgid "(HW ERROR)"
msgstr "(HV FEL)"
#: src/session.c:1000
msgid "Audio OFF"
msgstr "Ljud AV"
#: src/session.c:1000
msgid "Audio ON"
msgstr "Ljud PÅ"
#: src/session.c:1097
msgid "(BUSY)"
msgstr "(UPPTAGET)"
#: src/session.c:1103
msgid "(TIMEOUT)"
msgstr "(TIMEOUT)"
#: src/session.c:1139
msgid "(RUNG)"
msgstr "(RINGDE)"
#: src/session.c:1381
msgid "(ABORTED)"
msgstr "(AVBRUTEN)"
#: src/session.c:1389
msgid "(REJECTED)"
msgstr "(NEKAD)"

662
po/tr.po Normal file
View File

@ -0,0 +1,662 @@
# translation of ant-phone-0.1.4.tr.po to Turkish
# Copyright (C) 2004 Free Software Foundation, Inc.
# This file is distributed under the same license as the ant-phone package.
# Ayşegül Kurşun <roxelana_83@hotmail.com>, 2004.
#
msgid ""
msgstr ""
"Project-Id-Version: ant-phone 0.1.4\n"
"Report-Msgid-Bugs-To: stigge@antcom.de\n"
"POT-Creation-Date: 2004-04-03 18:51+0200\n"
"PO-Revision-Date: 2004-12-05 20:44+0200\n"
"Last-Translator: Ayşegül Kurşun <roxelana_83@hotmail.com>\n"
"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.3.1\n"
#: src/ant-phone.c:170
#, c-format
msgid ""
"Usage: %s [OPTION...]\n"
"\n"
"Options:\n"
" -h, --help Show this help message\n"
" -v, --version Print version information\n"
" -r, --cleanup Remove stale socket file (left by accident by\n"
" previous run)\n"
" -d, --debug[=level] Print additional runtime debugging data to stdout\n"
" level = 1..2\n"
" -i, --soundin=DEVICE OSS compatible device for input (recording),\n"
" default: /dev/dsp\n"
" -o, --soundout=DEVICE OSS compatible device for output (playback),\n"
" default: /dev/dsp\n"
" -m, --msn=MSN identifying MSN (for outgoing calls), 0 for "
"master\n"
" MSN of this termination/port\n"
" default: 0\n"
" -l, --msns=MSNS MSNs to listen on, semicolon-separated list or "
"'*'\n"
" default: *\n"
" -c, --call=NUMBER Call specified number\n"
"\n"
"Note: If arguments of --soundin and --soundout are equal, a full duplex\n"
" sound device is needed.\n"
msgstr ""
"Kullanım: %s [SEÇENEK...]\n"
"\n"
"Seçenekler:\n"
" -h, --help bu yardım iletisini gösterir\n"
" -v, --version Sürüm bilgilerini yazdırır\n"
" -r, --cleanup Eski soket dosyalarını siler (önceki işlemden\n"
" kazara kalmış)\n"
" -d, --debug[=seviye] Standart çıktıya ek hata ayıklama bilgisi "
"yazdırır\n"
" seviye = 1..2\n"
" -i, --soundin=AYGIT OSS uyumlu girdi aygıtları (kayıt için)\n"
" öntanımlı: /dev/dsp\n"
" -o, --soundout=AYGIT OSS uyumlu çıktı aygıtları (çalmak için)\n"
" öntanımlı: /dev/dsp\n"
" -m, --msn=MSN MSN tanımlama (dışarı aramalar), bu uç/port'un\n"
" ana MSN'i için 0\n"
" öntanımlı: 0\n"
" -l, --msns=MSNS Dinlenecek MSN'ler, noktalı virgül ile ayrılmış\n"
" liste ya da '*'\n"
" -c, --call=NUMARA Belirtilen numarayı arar\n"
"\n"
"Not: Eğer --soundin ve --soundout seçeneklerinin değerleri aynı ise,\n"
"tam duplex bir ses aygıtı gereklidir.\n"
#: src/ant-phone.c:221
#, c-format
msgid "Calling %s... "
msgstr "%s aranıyor..."
#: src/ant-phone.c:225
#, c-format
msgid "successful.\n"
msgstr "başarılı.\n"
#: src/callerid.c:131
msgid "Delete Entry"
msgstr "Girdiyi Sil"
#: src/callerid.c:143
msgid ""
"Are you sure you want to\n"
"delete this entry?"
msgstr ""
"Bu girdiyi silmek\n"
"istediğinize emin misiniz?"
#: src/callerid.c:148
msgid "Delete recording"
msgstr "Kaydı sil"
#: src/callerid.c:266
#, c-format
msgid "Enter the base filename for %s file"
msgstr "%s dosyasının temel dosya ismini girin"
#: src/callerid.c:312
msgid "Do you really want to delete this recording?"
msgstr "Gerçekten bu kaydı silmek istiyor musunuz?"
#: src/callerid.c:336 src/callerid.c:362
msgid "/_Playback"
msgstr "/_Çal"
#: src/callerid.c:337 src/callerid.c:366
msgid "/_Save as..."
msgstr "/_Farklı kaydet..."
#: src/callerid.c:338 src/callerid.c:370
msgid "/Delete _Recording"
msgstr "/Kaydı _Sil"
#: src/callerid.c:340 src/callerid.c:374
msgid "/_Delete Row"
msgstr "/S_atırı Sil"
#: src/callerid.c:423 src/gtksettings.c:455
msgid "Caller ID"
msgstr "Arayan Bilgisi"
#: src/callerid.c:426
msgid "Date/Time"
msgstr "Tarih/Zaman"
#: src/callerid.c:427
msgid "Type"
msgstr "Tür"
#: src/callerid.c:428
msgid "From"
msgstr "Kimden"
#: src/callerid.c:429
msgid "To"
msgstr "Kime"
#: src/callerid.c:430
msgid "Duration"
msgstr "Süre"
#: src/callerid.c:759
msgid "(UNKNOWN)"
msgstr "(BİLİNMEYEN)"
#: src/callerid.c:828
#, c-format
msgid "ANT: %d unanswered"
msgstr "ANT:%d cevaplanmamış"
#: src/controlpad.c:101
#, c-format
msgid "Preset %c"
msgstr "Önkurum %c"
#: src/controlpad.c:108
#, c-format
msgid "Please input new preset data for button %c:"
msgstr "Lütfen %c tuşu için yeni önkurum bilgisini girin"
#: src/controlpad.c:121
msgid "Name:"
msgstr "İsim:"
#: src/controlpad.c:124 src/gtk.c:561
msgid "Number:"
msgstr "Numara:"
#: src/controlpad.c:144 src/gtk.c:212 src/gtk.c:331 src/gtk.c:408
#: src/gtksettings.c:571 src/llcheck.c:422
msgid "OK"
msgstr "Tamam"
#: src/controlpad.c:157 src/gtksettings.c:616 src/session.c:68
msgid "Cancel"
msgstr "İptal"
#: src/controlpad.c:315
msgid "Backspace"
msgstr "Geri al"
#: src/controlpad.c:315
msgid "Preset 1"
msgstr "Önkurum 1"
#: src/controlpad.c:316
msgid "Clear Number"
msgstr "Numarayı Sil"
#: src/controlpad.c:316
msgid "Preset 2"
msgstr "Önkurum 2"
#: src/controlpad.c:317
msgid "Redial"
msgstr "Yeniden Ara"
#: src/controlpad.c:317
msgid "Preset 3"
msgstr "Önkurum 3"
#: src/controlpad.c:318
msgid "Mute Microphone"
msgstr "Mikrofonu Sessizleştir"
#: src/controlpad.c:318
msgid "Preset 4"
msgstr "Önkurum 4"
#: src/controlpad.c:351
msgid "Control"
msgstr "Kontrol"
#: src/controlpad.c:423
msgid "Recording"
msgstr "Kayıt"
#: src/controlpad.c:434
msgid "Record to file"
msgstr "Dosyaya kayıt"
#: src/controlpad.c:445
msgid "Record local channel"
msgstr "Yerel kanalları kaydet"
#: src/controlpad.c:456
msgid "Record remote channel"
msgstr "Uzak kanalları kaydet"
#: src/gtk.c:230 src/gtksettings.c:229
msgid "ANT Note"
msgstr "ANT Notu"
#: src/gtk.c:231
msgid ""
"Can't open audio device.\n"
"Please stop other applications using\n"
"the audio device(s) or check your\n"
"device settings and try again."
msgstr ""
"Ses aygıtıılamıyor. \n"
"Lütfen ses aygıt(lar)ını kullanan\n"
"diğer uygulamaları durdurun, ya da\n"
"aygıt ayarlarını kontrol edin\n"
"ve tekrar deneyin."
#: src/gtk.c:260
msgid "Sound input device:"
msgstr "Ses girdi aygıtı:"
#: src/gtk.c:261
msgid "Input speed:"
msgstr "Girdi hızı:"
#: src/gtk.c:261 src/gtk.c:264 src/gtk.c:265 src/gtk.c:267 src/gtk.c:271
#: src/gtk.c:274 src/gtk.c:275 src/gtk.c:277
msgid "[inactive]"
msgstr "[etkin değil]"
#: src/gtk.c:263
msgid "Input sample size (bits):"
msgstr "Girdi örnek boyu (bit):"
#: src/gtk.c:265 src/gtk.c:275
msgid "Input fragment size (samples):"
msgstr "Girdi parçacık boyu (örnek):"
#: src/gtk.c:267
msgid "Input channels:"
msgstr "Girdi kanalları:"
#: src/gtk.c:270
msgid "Sound output device:"
msgstr "Ses çıktı aygıtı:"
#: src/gtk.c:271
msgid "Output speed:"
msgstr "Çıktı hızı:"
#: src/gtk.c:273
msgid "Output sample size (bits):"
msgstr "Çıktı örnek boyu (bit):"
#: src/gtk.c:277
msgid "Output channels:"
msgstr "Çıktı kanalları:"
#: src/gtk.c:280
msgid "ISDN device:"
msgstr "ISDN aygıtı:"
#: src/gtk.c:281
msgid "ISDN speed (samples):"
msgstr "ISDN hızı (örnekler):"
#: src/gtk.c:282
msgid "ISDN sample size (bits):"
msgstr "ISDN örnek boyu (bit):"
#: src/gtk.c:283
msgid "ISDN fragment size (bytes):"
msgstr "ISDN parçacık boyu (bayt):"
#: src/gtk.c:295
msgid "ANT Info"
msgstr "ANT Bilgi"
#: src/gtk.c:366
msgid "About ANT"
msgstr "ANT hakkında"
#: src/gtk.c:382
#, c-format
msgid ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"This is an ISDN telephone application\n"
"written for GNU/Linux and ISDN4Linux for\n"
"communicating via a full duplex soundcard (or\n"
"multiple sound devices if you like) and an\n"
"audio capable ISDN4Linux ISDN device\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing list: ant-phone-devel@nongnu.org"
msgstr ""
"ANT (ANT bir telefon değildir) Sürüm %s\n"
"Telif hakkı 2002, 2003 Roland Stigge\n"
"\n"
"Bu bir ISDN telefon uygulamasıdır.\n"
"GNU/Linux ve ISDN4Linux için\n"
"yazılmıştır.\n"
"Tam dupleks ses kartları (veya çok sayıda\n"
"ses aygıtı) ve ses yetenekli ISDN4Linux\n"
"ISDN aygıtı kullanarak iletişim kurmak\n"
"için hazırlanmıştır.\n"
"\n"
"İletişim:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"E-Posta Listesi: ant-phone-devel@nongnu.org"
#: src/gtk.c:420
msgid "ANT License"
msgstr "ANT Lisansı"
#: src/gtk.c:421
msgid ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
msgstr ""
"ANT (ANT bir telefon değildir)\n"
"Telif Hakkı (C) 2002, 2003 Roland Stigge\n"
"\n"
"Bu program bir serbest yazılımdır. Bu yazılımı Free Software Foundation\n"
"tarafından yayınlanmış olan GNU Genel Kamu Lisansının 2. ya da daha sonraki\n"
"bir sürümünün koşulları altında kopyalayabilir, dağıtabilir ve/veya\n"
"üzerinde değişiklik yapabilirsiniz.\n"
"\n"
"Bu program kullanışlı olabileceği umularak dağıtılmaktadır. Ancak,\n"
"hiçbir GARANTİSİ YOKTUR; hatta SATILABİLİRLİĞİ veya HERHANGİ BİR\n"
"AMACA UYGUNLUĞU için bile garanti verilmez. Daha ayrıntılı bilgi\n"
"edinmek için GNU Genel Kamu Lisansına bakınız.\n"
"\n"
"GNU Genel Kamu Lisansının bir kopyasını bu yazılımla birlikte almış\n"
"olacaksınız; yoksa Free Software Foundation, Inc., 59 Temple Place\n"
"Suite 330, Boston, MA 02111-1307, USA. adresinden isteyebilirsiniz."
#: src/gtk.c:454
msgid "/Phon_e"
msgstr "/Telefon_"
#: src/gtk.c:455
msgid "/Phone/_Info Window"
msgstr "/Telefon/_Bilgi Penceresi"
#: src/gtk.c:456 src/gtk.c:504
msgid "/Phone/_Line Level Check"
msgstr "/Telefon/_Seviye Tespit Kontrolu"
#: src/gtk.c:458
msgid "/Phone/"
msgstr "/Telefon/"
#: src/gtk.c:459
msgid "/Phone/_Quit"
msgstr "/Telefon/_Vazgeçiş"
#: src/gtk.c:461
msgid "/_View"
msgstr "/_Görüntü"
#: src/gtk.c:462 src/gtk.c:492
msgid "/View/_Caller ID Monitor"
msgstr "/Görüntü/_Çağıran Birim Monitörü"
#: src/gtk.c:464 src/gtk.c:495
msgid "/View/_Line Level Meters"
msgstr "/Görüntü/_Satır Seviyesi Ölçümü"
#: src/gtk.c:466 src/gtk.c:498
msgid "/View/Control _Pad"
msgstr "/Görüntü/Kontrol_Yüzey"
#: src/gtk.c:468
msgid "/_Options"
msgstr "/_Seçenekler"
#: src/gtk.c:469 src/gtk.c:501
msgid "/Options/_Settings"
msgstr "/Seçenekler/_Ayarlar"
#: src/gtk.c:471
msgid "/_Help"
msgstr "/_Yardım"
#: src/gtk.c:472
msgid "/Help/_About"
msgstr "/Yardım/_Hakkında"
#: src/gtk.c:473
msgid "/Help/_License"
msgstr "/Yardım/_Lisans"
#: src/gtk.c:551 src/gtksettings.c:431 src/session.c:68
msgid "Dialing"
msgstr "Bağlantı"
#: src/gtk.c:783 src/gtk.c:784
msgid "MUTED"
msgstr "SESSİZ"
#: src/gtksettings.c:230
msgid "Bad isdn/sound device settings, please try again."
msgstr "Kötü isdn/SES aygıtı ayarları, lütfen tekrar deneyin"
#: src/gtksettings.c:293
msgid "ANT Settings"
msgstr "ANT Ayarları"
#: src/gtksettings.c:306
msgid "Application"
msgstr "Uygulamalar"
#: src/gtksettings.c:308
msgid "Options"
msgstr "Seçenekler"
#: src/gtksettings.c:320
msgid "Save options on exit"
msgstr "Çıkışta seçenekleri kaydedin"
#: src/gtksettings.c:327
msgid "Popup main window on incoming call"
msgstr "Gelen aramada ana pencereyi açar"
#: src/gtksettings.c:333
msgid "Execute on incoming call:"
msgstr "Gelen aramada çalıştırılır:"
#: src/gtksettings.c:344
msgid "Recording Format"
msgstr "Kayıt Biçemi"
#: src/gtksettings.c:354
msgid "Microsoft WAV, uLaw"
msgstr "Microsoft WAV, uLaw"
#: src/gtksettings.c:364
msgid "Microsoft WAV, 16-bit signed"
msgstr "Microsoft WAV, signed 16 bit "
#: src/gtksettings.c:374
msgid "Apple/SGI AIFF, uLaw"
msgstr "Apple/SGI AIFF, uLaw"
#: src/gtksettings.c:384
msgid "Apple/SGI AIFF, 16-bit signed"
msgstr "Apple/SGI AIFF, signed 16 bit"
#: src/gtksettings.c:397
msgid "Phone"
msgstr "Telefon"
#: src/gtksettings.c:399
msgid "ISDN"
msgstr "ISDN"
#: src/gtksettings.c:411
msgid "Identifying MSN:"
msgstr "MSN'i tanımlama:"
#: src/gtksettings.c:421
msgid "Listen to MSNs:"
msgstr "MSN'leri dinleyin:"
#: src/gtksettings.c:443
msgid "Dial history size:"
msgstr "Arama tarihçe boyutu:"
#: src/gtksettings.c:467
msgid "Maximum CID rows:"
msgstr "Maksimum CID satırı:"
#: src/gtksettings.c:475 src/gtksettings.c:503
msgid "[no limit]"
msgstr "[sınırsız]"
#: src/gtksettings.c:484
msgid "Read isdnlog data on startup"
msgstr "isdn kütük bilgisini başlangıçta okur"
#: src/gtksettings.c:491
msgid "Maximum days to read from isdnlog:"
msgstr "Isdn kütüğünden okunacak maksimum gün sayısı:"
#: src/gtksettings.c:520
msgid "Sound Devices"
msgstr "Ses Aygıtları"
#: src/gtksettings.c:522
msgid "OSS"
msgstr "OSS"
#: src/gtksettings.c:534
msgid "Input sound device:"
msgstr "Girdi ses aygıtı:"
#: src/gtksettings.c:546
msgid "Output sound device:"
msgstr "Çıktı ses aygıtı:"
#: src/gtksettings.c:559
msgid "Release unused devices"
msgstr "Kullanılmayan aygıtları serbest bırakır"
#: src/gtksettings.c:609
msgid "Save"
msgstr "Kaydet"
#: src/llcheck.c:371
msgid "Line Level Check"
msgstr "Ses Seviye Kontrolü"
#: src/llcheck.c:383
msgid ""
"Please check the line input level\n"
"and adjust it using your favorite\n"
"mixer application.\n"
"You can also play a sound\n"
"to test the sound output."
msgstr ""
"Lütfen ses girdi seviyesini\n"
"kontrol edin ve favori ses miksi\n"
"uygulamalarınızı kullanarak \n"
"ayarlayın. Ses çıktısını kontrol etmek için\n"
"bir ses çalabilirsiniz."
#: src/llcheck.c:405
msgid "Play sound"
msgstr "Ses çalar"
#: src/session.c:65
msgid "Ready"
msgstr "Hazır"
#: src/session.c:65
msgid "Dial"
msgstr "Bağlan"
#: src/session.c:65 src/session.c:69 src/session.c:70
msgid "Hang up"
msgstr "Telefonu kapa"
#: src/session.c:66 src/session.c:67
msgid "RING"
msgstr "ÇAL"
#: src/session.c:66 src/session.c:67
msgid "Answer"
msgstr "Cevap ver"
#: src/session.c:66 src/session.c:67
msgid "Reject"
msgstr "Reddet"
#: src/session.c:68 src/session.c:69 src/session.c:70 src/session.c:71
msgid "Pick up"
msgstr "Telefonu aç"
#: src/session.c:69
msgid "B-Channel open"
msgstr "B kanalıık"
#: src/session.c:70
msgid "Setup"
msgstr "Ayarlar"
#: src/session.c:71
msgid "Playback"
msgstr "Bantkaydı"
#: src/session.c:71
msgid "Stop"
msgstr "Dur"
#: src/session.c:377
#, c-format
msgid "Preset %d"
msgstr "%d'yi önkurun"
#: src/session.c:699
msgid "(HW ERROR)"
msgstr "(HW HATASI)"
#: src/session.c:1000
msgid "Audio OFF"
msgstr "Ses kapalı"
#: src/session.c:1000
msgid "Audio ON"
msgstr "Ses açık"
#: src/session.c:1097
msgid "(BUSY)"
msgstr "(MEŞGUL)"
#: src/session.c:1103
msgid "(TIMEOUT)"
msgstr "(ZAMAN AŞIMI)"
#: src/session.c:1139
msgid "(RUNG)"
msgstr "(ÇALMIŞ)"
#: src/session.c:1381
msgid "(ABORTED)"
msgstr "(DURDURULDU)"
#: src/session.c:1389
msgid "(REJECTED)"
msgstr "(REDDEDİLDİ)"

666
po/vi.po Normal file
View File

@ -0,0 +1,666 @@
# Vietnamese translation for ant-phone-0.1.4.
# Copyright © 2005 Roland Stigge
# This file is distributed under the same license as the ant-phone-0.1.4 package.
# Clytie Siddall <clytie@riverland.net.au>, 2005.
#
msgid ""
msgstr ""
"Project-Id-Version: ant-phone 0.1.4\n"
"Report-Msgid-Bugs-To: stigge@antcom.de\n"
"POT-Creation-Date: 2004-04-03 18:51+0200\n"
"PO-Revision-Date: 2005-04-11 17:21+0930\n"
"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
"Language-Team: Vietnamese <gnomevi-list@lists.sourceforge.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/ant-phone.c:170
#, c-format
msgid ""
"Usage: %s [OPTION...]\n"
"\n"
"Options:\n"
" -h, --help Show this help message\n"
" -v, --version Print version information\n"
" -r, --cleanup Remove stale socket file (left by accident by\n"
" previous run)\n"
" -d, --debug[=level] Print additional runtime debugging data to stdout\n"
" level = 1..2\n"
" -i, --soundin=DEVICE OSS compatible device for input (recording),\n"
" default: /dev/dsp\n"
" -o, --soundout=DEVICE OSS compatible device for output (playback),\n"
" default: /dev/dsp\n"
" -m, --msn=MSN identifying MSN (for outgoing calls), 0 for "
"master\n"
" MSN of this termination/port\n"
" default: 0\n"
" -l, --msns=MSNS MSNs to listen on, semicolon-separated list or "
"'*'\n"
" default: *\n"
" -c, --call=NUMBER Call specified number\n"
"\n"
"Note: If arguments of --soundin and --soundout are equal, a full duplex\n"
" sound device is needed.\n"
msgstr ""
"Cách sử dụng: %s [TÙY_CHỌN...]\n"
"\n"
"Tùy chọn:\n"
" -h, --help Hiển thị thông điệp _trợ giúp_ này\n"
" -v, --version Hiển thị thông tin _phiên bản_\n"
" -r, --cleanup Bỏ tập tin ổ cắm cũ (còn lại bất ngờ sau chạy "
"trước) (_xóa_) -d, --debug[=MỨC] In dữ liệu _gỡ lỗi_ thời chạy thêm xuất "
"thiết bị xuất chuẩn (stdout)\n"
" MỨC = 1..2\n"
" -i, --soundin=THIIẾT_BỊ thiết bị gõ tương thích với phần mềm nguồn mở "
"(ghi)\n"
"\t\t\t\t(_âm thành vào_) mặc định: /dev/dsp\n"
" -o, --soundout=THIẾT_BỊ thiết bị xuất tương thích với phần mềm nguồn mở "
"(phát)\n"
"\t\t\t\t(_âm thành ra_) mặc định: /dev/dsp\n"
" -m, --msn=SỐ số đa người ký tên (Multiple Subscriber Number: MSN) "
"nhận biết để gọi qua điện thoại,\n"
"\t\t\t0 cho MSN chính của cổng/thiết bị cuối này, mặc định: 0\n"
" -l, --msns=NHỮNG_SỐ Những MSN để nghe qua, danh sách phân cách bằng dấu "
"phẩy\n"
"\t\t\thay dấu sao '*', mặc định: *\n"
" -c, --call=SỐ _gọi_ số điện thoại ấy\n"
"\n"
"Ghi chú: nếu hai đối số --soundin (âm thành vào) và --soundout (âm thành "
"xuất\n"
"là bằng nhau thì cần thiết bị âm thành truyền dẫn hai chiếu đầy đủ (full "
"duplex).\n"
#: src/ant-phone.c:221
#, c-format
msgid "Calling %s... "
msgstr "Gọi %s..."
#: src/ant-phone.c:225
#, c-format
msgid "successful.\n"
msgstr "được rồi.\n"
#: src/callerid.c:131
msgid "Delete Entry"
msgstr "Xóa bỏ mục"
#: src/callerid.c:143
msgid ""
"Are you sure you want to\n"
"delete this entry?"
msgstr ""
"Bạn có chắc muốn xóa bỏ\n"
"mục này không?"
#: src/callerid.c:148
msgid "Delete recording"
msgstr "Xóa bỏ mục ghi"
#: src/callerid.c:266
#, c-format
msgid "Enter the base filename for %s file"
msgstr "Hãy nhập tên tập tin cơ bản cho tập tin %s"
#: src/callerid.c:312
msgid "Do you really want to delete this recording?"
msgstr "Bạn chắc muốn xóa bỏ mục ghi này không?"
#: src/callerid.c:336 src/callerid.c:362
msgid "/_Playback"
msgstr "/_Phát lại"
#: src/callerid.c:337 src/callerid.c:366
msgid "/_Save as..."
msgstr "/_Lưu là..."
#: src/callerid.c:338 src/callerid.c:370
msgid "/Delete _Recording"
msgstr "/Xóa bỏ mục _ghi"
#: src/callerid.c:340 src/callerid.c:374
msgid "/_Delete Row"
msgstr "/Xóa bỏ _hàng"
#: src/callerid.c:423 src/gtksettings.c:455
msgid "Caller ID"
msgstr "Xem số người gọi"
#: src/callerid.c:426
msgid "Date/Time"
msgstr "Ngày/Giờ"
#: src/callerid.c:427
msgid "Type"
msgstr "Loại"
#: src/callerid.c:428
msgid "From"
msgstr "Từ"
#: src/callerid.c:429
msgid "To"
msgstr "Cho"
#: src/callerid.c:430
msgid "Duration"
msgstr "Thời gian"
#: src/callerid.c:759
msgid "(UNKNOWN)"
msgstr "(không biết)"
#: src/callerid.c:828
#, c-format
msgid "ANT: %d unanswered"
msgstr "ANT: %d chưa trả lời"
#: src/controlpad.c:101
#, c-format
msgid "Preset %c"
msgstr "Lập trước %c"
#: src/controlpad.c:108
#, c-format
msgid "Please input new preset data for button %c:"
msgstr "Hãy nhập dữ liệu lập trước mới cho cái nút %c:"
#: src/controlpad.c:121
msgid "Name:"
msgstr "Tên:"
#: src/controlpad.c:124 src/gtk.c:561
msgid "Number:"
msgstr "Số đt:"
#: src/controlpad.c:144 src/gtk.c:212 src/gtk.c:331 src/gtk.c:408
#: src/gtksettings.c:571 src/llcheck.c:422
msgid "OK"
msgstr "Được"
#: src/controlpad.c:157 src/gtksettings.c:616 src/session.c:68
msgid "Cancel"
msgstr "Thôi"
#: src/controlpad.c:315
msgid "Backspace"
msgstr "Phím Xóa lùi"
#: src/controlpad.c:315
msgid "Preset 1"
msgstr "Lập trước 1"
#: src/controlpad.c:316
msgid "Clear Number"
msgstr "Xóa số"
#: src/controlpad.c:316
msgid "Preset 2"
msgstr "Lập trước 2"
#: src/controlpad.c:317
msgid "Redial"
msgstr "Quay số lại"
#: src/controlpad.c:317
msgid "Preset 3"
msgstr "Lập trước 3"
#: src/controlpad.c:318
msgid "Mute Microphone"
msgstr "Tắt máy vi âm"
#: src/controlpad.c:318
msgid "Preset 4"
msgstr "Lập trước 4"
#: src/controlpad.c:351
msgid "Control"
msgstr "Điều khiển"
#: src/controlpad.c:423
msgid "Recording"
msgstr "Ghi"
#: src/controlpad.c:434
msgid "Record to file"
msgstr "Ghi vào tập tin"
#: src/controlpad.c:445
msgid "Record local channel"
msgstr "Ghi kênh địa phương"
#: src/controlpad.c:456
msgid "Record remote channel"
msgstr "Ghi kênh từ xa"
#: src/gtk.c:230 src/gtksettings.c:229
msgid "ANT Note"
msgstr "Ant: chú thích"
#: src/gtk.c:231
msgid ""
"Can't open audio device.\n"
"Please stop other applications using\n"
"the audio device(s) or check your\n"
"device settings and try again."
msgstr ""
"Không mở được thiết bị âm thanh.\n"
"Hãy thôi các thiết bị khác sử dụng\n"
"cùng thiết bị âm thanh ấy hay kiểm tra\n"
"thiết lập thiết bị và thử lại."
#: src/gtk.c:260
msgid "Sound input device:"
msgstr "Thiết bị gõ âm thanh:"
#: src/gtk.c:261
msgid "Input speed:"
msgstr "Tốc độ gõ:"
#: src/gtk.c:261 src/gtk.c:264 src/gtk.c:265 src/gtk.c:267 src/gtk.c:271
#: src/gtk.c:274 src/gtk.c:275 src/gtk.c:277
msgid "[inactive]"
msgstr "[không làm gì]"
#: src/gtk.c:263
msgid "Input sample size (bits):"
msgstr "Cỡ mẫu gõ (theo bit):"
#: src/gtk.c:265 src/gtk.c:275
msgid "Input fragment size (samples):"
msgstr "Cỡ mảnh gõ (theo mẫu):"
#: src/gtk.c:267
msgid "Input channels:"
msgstr "Kênh gõ:"
#: src/gtk.c:270
msgid "Sound output device:"
msgstr "Thiết bị âm thanh xuất:"
#: src/gtk.c:271
msgid "Output speed:"
msgstr "Tốc độ xuất:"
#: src/gtk.c:273
msgid "Output sample size (bits):"
msgstr "Cỡ mẫu xuât (theo bit):"
#: src/gtk.c:277
msgid "Output channels:"
msgstr "Kênh xuất:"
#: src/gtk.c:280
msgid "ISDN device:"
msgstr "Thiết bị ISDN:"
#: src/gtk.c:281
msgid "ISDN speed (samples):"
msgstr "Tốc độ ISDN (theo mẫu):"
#: src/gtk.c:282
msgid "ISDN sample size (bits):"
msgstr "Cỡ mẫu ISDN (theo bit):"
#: src/gtk.c:283
msgid "ISDN fragment size (bytes):"
msgstr "Cỡ mảnh ISDN (theo byte):"
#: src/gtk.c:295
msgid "ANT Info"
msgstr "Thông tin ANT"
#: src/gtk.c:366
msgid "About ANT"
msgstr "Giới thiệu ANT"
#: src/gtk.c:382
#, c-format
msgid ""
"ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n"
"\n"
"This is an ISDN telephone application\n"
"written for GNU/Linux and ISDN4Linux for\n"
"communicating via a full duplex soundcard (or\n"
"multiple sound devices if you like) and an\n"
"audio capable ISDN4Linux ISDN device\n"
"\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing list: ant-phone-devel@nongnu.org"
msgstr ""
"ANT (ANT is Not a Telephone) phiên bản %s\n"
"(ANT không phải là một máy điện thoại)Bản quyền © năm 2002, 2003 Roland "
"Stigge\n"
"\n"
"Đây là một ứng dụng điện thoai ISDN\n"
"được tạo cho GNU/Linux và ISDN4Linux\n"
"để truyền thông qua thẻ âm thanh truyền dẫn\n"
"hai chiếu đầy đủ (hay số nhiều thiết bị nếu muốn)\n"
"và thiết bị ISDN ISDN4Linux có thể gởi âm thanh.\n"
"\n"
"Liên hệ:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Hộp thư chung: ant-phone-devel@nongnu.org"
#: src/gtk.c:420
msgid "ANT License"
msgstr "Quyền ANT"
#: src/gtk.c:421
msgid ""
"ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
msgstr ""
"ANT (ANT is Not a Telephone)\n"
"Bản quyền © năm 2002, 2003 Roland Stigge\n"
"\n"
"Chương trình này là phần mềm tự do; bạn có thể phân phối nó lại và/hay\n"
"sửa đổi nó theo điều kiện của Quyền Công Chung Gnu (GPL)\n"
"như xuất do Tổ chức Phần mềm Tự do (Free Software Foundation)\n"
"hoặc phiên bản 2 của quyền ấy hoặc (tùy chọn) bất cứ phiên bản sau nào.\n"
"\n"
"Chúng tôi phân phối chương trình này vì mong nó hữu ích,\n"
"nhưng nó không bảo đảm gì cả, không có bảo đảm ngụ ý ngay cả\n"
"khả năng bán hay khả năng làm việc dứt khoát.\n"
"Hãy xem Quyền Công Chung Gnu (GPL) để tìm chi tiết.\n"
"\n"
"Nếu bạn chưa nhận một bản Quyền Công Chung Gnu\n"
"(Gnu General Public Licence) cùng với chương trinh này thì hãy\n"
"viết cho Tổ chức Phần mềm Tự do:\n"
"Free SoftwareFoundation, Inc.,\n"
"59 Temple Place - Suite 330,\n"
"Boston, MA 02111-1307, USA (Mỹ)."
#: src/gtk.c:454
msgid "/Phon_e"
msgstr "/_Điện thoại"
#: src/gtk.c:455
msgid "/Phone/_Info Window"
msgstr "/Điện thoại/Cửa sổ thông t_in"
#: src/gtk.c:456 src/gtk.c:504
msgid "/Phone/_Line Level Check"
msgstr "/Điện thoại/Kiểm tra mức _dòng"
#: src/gtk.c:458
msgid "/Phone/"
msgstr "/Điện thoại/"
#: src/gtk.c:459
msgid "/Phone/_Quit"
msgstr "/Điện thoại/_Thoát"
#: src/gtk.c:461
msgid "/_View"
msgstr "/_Xem"
#: src/gtk.c:462 src/gtk.c:492
msgid "/View/_Caller ID Monitor"
msgstr "/Xem/Theo dõi số người dùng"
#: src/gtk.c:464 src/gtk.c:495
msgid "/View/_Line Level Meters"
msgstr "/Xem/Đo mức _dòng"
#: src/gtk.c:466 src/gtk.c:498
msgid "/View/Control _Pad"
msgstr "/Xem/_Bảng điều khiển"
#: src/gtk.c:468
msgid "/_Options"
msgstr "/Tùy _chọn"
#: src/gtk.c:469 src/gtk.c:501
msgid "/Options/_Settings"
msgstr "/Tùy chọn/Thiết _lập"
#: src/gtk.c:471
msgid "/_Help"
msgstr "/Trợ _giúp"
#: src/gtk.c:472
msgid "/Help/_About"
msgstr "/Trợ giúp/_Giới thiệu"
#: src/gtk.c:473
msgid "/Help/_License"
msgstr "/Trợ giúp/_Quyền"
#: src/gtk.c:551 src/gtksettings.c:431 src/session.c:68
msgid "Dialing"
msgstr "Quay số"
#: src/gtk.c:783 src/gtk.c:784
msgid "MUTED"
msgstr "Tắt tiếng rồi"
#: src/gtksettings.c:230
msgid "Bad isdn/sound device settings, please try again."
msgstr "Có thiết lập thiết bị ISDN/âm thanh sai nên hay thử lại."
#: src/gtksettings.c:293
msgid "ANT Settings"
msgstr "Thiết lập ANT"
#: src/gtksettings.c:306
msgid "Application"
msgstr "Ứng dụng"
#: src/gtksettings.c:308
msgid "Options"
msgstr "Tùy chọn"
#: src/gtksettings.c:320
msgid "Save options on exit"
msgstr "Lưu tùy chọn khi thoát"
#: src/gtksettings.c:327
msgid "Popup main window on incoming call"
msgstr "Bật lên cửa sổ chính khi nhận sự gọi"
#: src/gtksettings.c:333
msgid "Execute on incoming call:"
msgstr "Thi hành khi nhận sự gọi"
#: src/gtksettings.c:344
msgid "Recording Format"
msgstr "Dạng ghi"
#: src/gtksettings.c:354
msgid "Microsoft WAV, uLaw"
msgstr "Microsoft WAV, uLaw"
#: src/gtksettings.c:364
msgid "Microsoft WAV, 16-bit signed"
msgstr "Microsoft WAV, 16-bit đã ký tên"
#: src/gtksettings.c:374
msgid "Apple/SGI AIFF, uLaw"
msgstr "Apple/SGI AIFF, uLaw"
#: src/gtksettings.c:384
msgid "Apple/SGI AIFF, 16-bit signed"
msgstr "Apple/SGI AIFF, 16-bit đã ký tên"
#: src/gtksettings.c:397
msgid "Phone"
msgstr "Điện thoại"
#: src/gtksettings.c:399
msgid "ISDN"
msgstr "ISDN"
#: src/gtksettings.c:411
msgid "Identifying MSN:"
msgstr "Số đa người ký tên (Multiplê Subscriber Number: MSN) nhân biết:"
#: src/gtksettings.c:421
msgid "Listen to MSNs:"
msgstr "Nghe qua những số đa người ký tên (MSN) này:"
#: src/gtksettings.c:443
msgid "Dial history size:"
msgstr "Cỡ lịch sử quay số:"
#: src/gtksettings.c:467
msgid "Maximum CID rows:"
msgstr "Tối đa hàng số người gởi:"
#: src/gtksettings.c:475 src/gtksettings.c:503
msgid "[no limit]"
msgstr "[vô vùng] "
#: src/gtksettings.c:484
msgid "Read isdnlog data on startup"
msgstr "Đọc dữ liệu isdnlog (bản ghi ISDN) khi khởi động"
#: src/gtksettings.c:491
msgid "Maximum days to read from isdnlog:"
msgstr "Đọc từ isdnlog (bản ghi ISDN) được số ngày (tối đa):"
#: src/gtksettings.c:520
msgid "Sound Devices"
msgstr "Thiết bị âm thanh"
#: src/gtksettings.c:522
msgid "OSS"
msgstr "Phần mềm nguồn mở tự do"
#: src/gtksettings.c:534
msgid "Input sound device:"
msgstr "Thiết bị âm thanh gõ:"
#: src/gtksettings.c:546
msgid "Output sound device:"
msgstr "Thiết bị âm thanh xuất:"
#: src/gtksettings.c:559
msgid "Release unused devices"
msgstr "Nhả các thiết bị chưa sử dụng lại"
#: src/gtksettings.c:609
msgid "Save"
msgstr "Lưu"
#: src/llcheck.c:371
msgid "Line Level Check"
msgstr "Kiểm tra mức dòng"
#: src/llcheck.c:383
msgid ""
"Please check the line input level\n"
"and adjust it using your favorite\n"
"mixer application.\n"
"You can also play a sound\n"
"to test the sound output."
msgstr ""
"Hãy kiểm tra mức gõ dòng\n"
"và điều chỉnh nó bằng ứng dụng\n"
"hoà tiếng ưa thích của bạn.\n"
"Bạn cũng có thể phát tiếng\n"
"để thử xuất âm thanh ra."
#: src/llcheck.c:405
msgid "Play sound"
msgstr "Phát âm thanh"
#: src/session.c:65
msgid "Ready"
msgstr "Sẵn sàng"
#: src/session.c:65
msgid "Dial"
msgstr "Quay số"
#: src/session.c:65 src/session.c:69 src/session.c:70
msgid "Hang up"
msgstr "Ngừng nói"
#: src/session.c:66 src/session.c:67
msgid "RING"
msgstr "REO"
#: src/session.c:66 src/session.c:67
msgid "Answer"
msgstr "Trả lời"
#: src/session.c:66 src/session.c:67
msgid "Reject"
msgstr "Loại ra"
#: src/session.c:68 src/session.c:69 src/session.c:70 src/session.c:71
msgid "Pick up"
msgstr "Lấy"
#: src/session.c:69
msgid "B-Channel open"
msgstr "Kênh-B mở"
#: src/session.c:70
msgid "Setup"
msgstr "Thiết lập"
#: src/session.c:71
msgid "Playback"
msgstr "Phát lại"
#: src/session.c:71
msgid "Stop"
msgstr "Ngừng"
#: src/session.c:377
#, c-format
msgid "Preset %d"
msgstr "Lập trước %d"
#: src/session.c:699
msgid "(HW ERROR)"
msgstr "(Lỗi phần cứng)"
#: src/session.c:1000
msgid "Audio OFF"
msgstr "TẮT âm thanh"
#: src/session.c:1000
msgid "Audio ON"
msgstr "MỞ âm thanh"
#: src/session.c:1097
msgid "(BUSY)"
msgstr "(BẬN)"
#: src/session.c:1103
msgid "(TIMEOUT)"
msgstr "(HẾT THỜI)"
#: src/session.c:1139
msgid "(RUNG)"
msgstr "(REO RỒI)"
#: src/session.c:1381
msgid "(ABORTED)"
msgstr "(BỊ HỦY BỎ RỒI)"
#: src/session.c:1389
msgid "(REJECTED)"
msgstr "(LOẠI BỎ RỒI)"

11
src/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
ant-phone
calleridlexer.c
calleridparser.c
calleridparser.h
gettext.h
isdnlexer.c
isdnparser.c
isdnparser.h
*.o
.deps

88
src/Makefile.am Normal file
View File

@ -0,0 +1,88 @@
## Process this file with automake to produce Makefile.in
PACKAGE = @PACKAGE@
VERSION = @VERSION@
bin_PROGRAMS = ant-phone
ant_phone_SOURCES = \
ant-phone.c \
callerid.c \
g711.c \
gtk.c \
isdn.c \
llcheck.c \
mediation.c \
session.c \
sound.c \
util.c \
settings.c \
calleridlexer.l \
calleridparser.y \
isdnlexer.l \
isdnparser.y \
gtksettings.c \
controlpad.c \
fxgenerator.c \
server.c \
client.c \
recording.c \
isdntree.c
noinst_HEADERS = \
callerid.h \
g711.h \
gtk.h \
isdn.h \
llcheck.h \
mediation.h \
session.h \
sound.h \
util.h \
settings.h \
gtksettings.h \
controlpad.h \
fxgenerator.h \
server.h \
client.h \
recording.h \
globals.h \
gettext.h \
isdnlexer.h \
isdntree.h
EXTRA_DIST = \
pickup.xpm \
hangup.xpm \
in.xpm \
out.xpm \
backspace.xpm \
redial.xpm \
mute.xpm \
aboutlogo.xpm \
record.xpm \
icon16x16.xpm \
icon32x32.xpm \
icon48x48.xpm \
icon64x64.xpm
top_srcdir = @top_srcdir@
subdir = src
datadir = @datadir@
localedir = $(datadir)/locale
DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
LIBS = @LIBINTL@ @LIBS@
INCLUDES = -I../intl -I$(top_srcdir)/intl @DEPS_CFLAGS@
AM_CFLAGS = -DVERSION='"@VERSION@"' -DPACKAGE='"@PACKAGE@"' @CFLAGS@
AM_LDFLAGS = @DEPS_LIBS@
LDADD = @LEXLIB@
AM_YFLAGS = -d
##YFLAGS = -d
AM_LFLAGS=-olex.yy.c
##LFLAGS=-Pcallerid
BUILT_SOURCES = isdnparser.h calleridparser.h

338
src/aboutlogo.xpm Normal file
View File

@ -0,0 +1,338 @@
/* XPM */
static char * aboutlogo_xpm[] = {
"150 83 252 2",
" g None",
". g #FFFFFF",
"+ g #FEFEFE",
"@ g #F5F5F5",
"# g #E4E4E4",
"$ g #C0C0C0",
"% g #B8B8B8",
"& g #B3B3B3",
"* g #B5B5B5",
"= g #BEBEBE",
"- g #CACACA",
"; g #EFEFEF",
"> g #9B9B9B",
", g #656565",
"' g #373737",
") g #262626",
"! g #1C1C1C",
"~ g #070707",
"{ g #030303",
"] g #000000",
"^ g #020202",
"/ g #060606",
"( g #0D0D0D",
"_ g #232323",
": g #4E4E4E",
"< g #A0A0A0",
"[ g #E6E6E6",
"} g #B6B6B6",
"| g #636363",
"1 g #222222",
"2 g #080808",
"3 g #010101",
"4 g #848484",
"5 g #FDFDFD",
"6 g #DDDDDD",
"7 g #7F7F7F",
"8 g #1B1B1B",
"9 g #292929",
"0 g #C1C1C1",
"a g #DCDCDC",
"b g #6E6E6E",
"c g #111111",
"d g #A8A8A8",
"e g #FCFCFC",
"f g #F9F9F9",
"g g #A9A9A9",
"h g #242424",
"i g #0A0A0A",
"j g #9A9A9A",
"k g #E9E9E9",
"l g #818181",
"m g #616161",
"n g #585858",
"o g #626262",
"p g #A1A1A1",
"q g #CDCDCD",
"r g #ECECEC",
"s g #FBFBFB",
"t g #EDEDED",
"u g #8E8E8E",
"v g #0F0F0F",
"w g #2A2A2A",
"x g #7C7C7C",
"y g #D6D6D6",
"z g #F4F4F4",
"A g #C4C4C4",
"B g #838383",
"C g #8B8B8B",
"D g #767676",
"E g #DFDFDF",
"F g #BABABA",
"G g #1A1A1A",
"H g #8C8C8C",
"I g #F2F2F2",
"J g #F6F6F6",
"K g #AEAEAE",
"L g #959595",
"M g #AFAFAF",
"N g #D0D0D0",
"O g #F7F7F7",
"P g #464646",
"Q g #050505",
"R g #575757",
"S g #F0F0F0",
"T g #A5A5A5",
"U g #DEDEDE",
"V g #CCCCCC",
"W g #565656",
"X g #B4B4B4",
"Y g #8A8A8A",
"Z g #C5C5C5",
"` g #D5D5D5",
" . g #6C6C6C",
".. g #141414",
"+. g #DBDBDB",
"@. g #D7D7D7",
"#. g #B9B9B9",
"$. g #EEEEEE",
"%. g #727272",
"&. g #939393",
"*. g #E7E7E7",
"=. g #AAAAAA",
"-. g #3F3F3F",
";. g #676767",
">. g #151515",
",. g #909090",
"'. g #4D4D4D",
"). g #6D6D6D",
"!. g #A3A3A3",
"~. g #9D9D9D",
"{. g #7E7E7E",
"]. g #828282",
"^. g #757575",
"/. g #7B7B7B",
"(. g #868686",
"_. g #BDBDBD",
":. g #E5E5E5",
"<. g #363636",
"[. g #040404",
"}. g #8F8F8F",
"|. g #858585",
"1. g #B0B0B0",
"2. g #777777",
"3. g #171717",
"4. g #272727",
"5. g #F8F8F8",
"6. g #A7A7A7",
"7. g #989898",
"8. g #C8C8C8",
"9. g #E1E1E1",
"0. g #E0E0E0",
"a. g #C7C7C7",
"b. g #414141",
"c. g #090909",
"d. g #535353",
"e. g #969696",
"f. g #F3F3F3",
"g. g #404040",
"h. g #FAFAFA",
"i. g #C6C6C6",
"j. g #606060",
"k. g #0C0C0C",
"l. g #BBBBBB",
"m. g #3D3D3D",
"n. g #505050",
"o. g #474747",
"p. g #BFBFBF",
"q. g #686868",
"r. g #787878",
"s. g #3E3E3E",
"t. g #2B2B2B",
"u. g #E3E3E3",
"v. g #D4D4D4",
"w. g #121212",
"x. g #303030",
"y. g #EBEBEB",
"z. g #EAEAEA",
"A. g #F1F1F1",
"B. g #6B6B6B",
"C. g #9E9E9E",
"D. g #4C4C4C",
"E. g #4A4A4A",
"F. g #101010",
"G. g #5D5D5D",
"H. g #ABABAB",
"I. g #D3D3D3",
"J. g #D8D8D8",
"K. g #CFCFCF",
"L. g #696969",
"M. g #666666",
"N. g #2C2C2C",
"O. g #ADADAD",
"P. g #A6A6A6",
"Q. g #B2B2B2",
"R. g #B1B1B1",
"S. g #393939",
"T. g #333333",
"U. g #C3C3C3",
"V. g #7D7D7D",
"W. g #747474",
"X. g #5A5A5A",
"Y. g #888888",
"Z. g #919191",
"`. g #9C9C9C",
" + g #BCBCBC",
".+ g #C2C2C2",
"++ g #D2D2D2",
"@+ g #8D8D8D",
"#+ g #7A7A7A",
"$+ g #646464",
"%+ g #595959",
"&+ g #717171",
"*+ g #5B5B5B",
"=+ g #0E0E0E",
"-+ g #0B0B0B",
";+ g #5E5E5E",
">+ g #999999",
",+ g #878787",
"'+ g #484848",
")+ g #454545",
"!+ g #323232",
"~+ g #1D1D1D",
"{+ g #A4A4A4",
"]+ g #1F1F1F",
"^+ g #424242",
"/+ g #191919",
"(+ g #6F6F6F",
"_+ g #131313",
":+ g #202020",
"<+ g #B7B7B7",
"[+ g #9F9F9F",
"}+ g #2F2F2F",
"|+ g #161616",
"1+ g #515151",
"2+ g #181818",
"3+ g #5C5C5C",
"4+ g #898989",
"5+ g #2E2E2E",
"6+ g #444444",
"7+ g #4B4B4B",
"8+ g #3C3C3C",
"9+ g #979797",
"0+ g #CBCBCB",
"a+ g #E2E2E2",
"b+ g #383838",
"c+ g #343434",
"d+ g #808080",
"e+ g #5F5F5F",
"f+ g #929292",
"g+ g #1E1E1E",
"h+ g #A2A2A2",
"i+ g #434343",
"j+ g #6A6A6A",
"k+ g #E8E8E8",
"l+ g #212121",
"m+ g #797979",
"n+ g #282828",
"o+ g #545454",
"p+ g #707070",
"q+ g #C9C9C9",
"r+ g #949494",
"s+ g #ACACAC",
"t+ g #D1D1D1",
"u+ g #555555",
"v+ g #3A3A3A",
"w+ g #737373",
"x+ g #494949",
"y+ g #2D2D2D",
"z+ g #353535",
"A+ g #D9D9D9",
"B+ g #DADADA",
"C+ g #4F4F4F",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ # $ % & & * = - ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ $ > , ' ) ! ~ { ] ] ^ / ( _ : < [ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . @ } | 1 2 3 ] ] ] ] ] ] ] ] ] ] ] ] ] { _ 4 ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . 5 6 7 8 { ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 9 0 + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . + a b c ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] c d e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . f g h 3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] i j k 0 l m n n o b p q r . . . . . . . . . . . . . . . . . . . . . . . . . . s t + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . s u v ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] c ) / ] ] ] ] ] ] ] ~ w x y + . . . . . . . . . . . . . . . . . . z A u B C B D E . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . F c ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] G H I . . . . . . . . . . . . . . . J K L M N E O 5 + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . @ P ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Q R S . . . . . . . . . . . . . N T U 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . V ~ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 W z . . . . . . . . . . . = X e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . Y ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Q B + . . . . . . . . + Z ` . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . + .] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ..+.. . . . . . . . @.#.+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z $.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . + | ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] %.. . . . . . . z &.I . . . . . . . . . . + O [ *.$.+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; =.-.&.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . + ;.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] >.S . + y ,.'.).Y !.. . . . . . . [ F ~.{.C ].^.^./.(.4 _.. . . . . . . . . . . . . . . . . . . . . . . . . . . :.&.<.[.] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . |.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 1.I 2.3.3 ] ] ] 4.> 5.. + [ 6.4 7.8.U k e + . . + O 9.` . . . . . . . . . . . . . . . . . . . . . . . . . 0.l 1 [.] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . a.Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] b.: ^ ] ] ] ] ] ] c.d.(./.e.9.f.+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a ).3.^ ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . z g.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] {.+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . h.i.j.k.] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . l.>.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Q m.~.1 c.{ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] n.s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f.% o.c.] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . e 7.>.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] i x f.p.q.p.M r.c.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ! @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $.p s.Q ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . s } ' ^ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ t.T f u.v.f . . J m Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] w.[.] ] ] ] ] ] ] ] ] ] x.O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . y.j b.[.] ] ] ] ] ] ] ] ] ] ] 3 8 r.U + v.z.. . . . . A.B.( ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] [.o.v.! ] ] ] ] ] ] ] ] ] ] j.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . @ N 7 -.( ] ] ] ] ] ] >.D.C u.e . U v.+ . . . . . . f % E.F.] ] ] ] ] ] ] ] ] ] ] ] ..}.; + G.] ] ] ] ] ] ] ] ] Q H.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . s I I.=.u u g J.z e . . . :.K.+ . . . . . . . . . s y.T t.^././.{.{./.L.M.%.m & + . . X ~ ] ] ] ] ] ] ] ] N.$.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z O.s . . . . . . . . . . . . * b 5 . . . . . . . . [ P.. . . f ;.Q ] ] ] ] ] ] >.Q.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + R.$.. . . . . . . . . . . . y.).*.. . . . . . . . . + < f.. . . J 7.S.F./ / 2 T.K s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u.1.. . . . . . . . . . . . . u P.. . . . . . . . . . . $ 0 . . . . . O K.p.p.U.; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + T $.. . . . . . . . . . . . I 7 z . . . . . . . . . . . A.j e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . 5 ; J.#.j C V.W.G.R R R R X.%.D Y.Z.`.].+.I 5 . . . . . . . . . . +.+. . . . . . . . . . . . . P.# . . . . . . . . . . . . . I ++p @+#+$+R R %+&+B j = [ e . . . . . . . . . . . . . . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ,.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . + +.j *+x.=+i Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] ..F.-+v T.;+>+0.+ . . . . . s `.f . e.,+|.).).).).).).D %.).d.'+O . . . . . . . . + y C P c i ^ ] ] ] ] ] ] ] ] 3 / ( 9 ;.& O . . . . . . . . D ).).).).).)+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] <.).).).).).).).).).)._.. . . . . . ",
". . . . . . . . . . . . . . e E C !+^ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] [.~+] ] ] ] ] ] 3 m.{+z.+ . . :.=.. . ]+] ] ] ] ] ] ] ] [.G { ] ] t . . . . . . S d ^+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] /+7 +.e . . . . . F.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . ",
". . . . . . . . . . . . . U (+w.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] _+=+] ] ] ] ] ] ] ] ] :+Y.k . <+0 . . ]+] ] ] ] ] ] ] ] ] c ..3 ] #.. . . . I < t.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] _+b *.. . . . F.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . ",
". . . . . . . . . . . f [+~+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] F.v ] ] ] ] ] ] ] ] ] ] [.}+X &.f . . ]+] ] ] ] ] ] ] ] ] { 3.2 ] #.. . 5 Z P ~ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] !+ ++ . . F.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . ",
". . . . . . . . . . ; W.2 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ~+3 ] ] ] ] ] ] ] ] ] ] ] ] i n h.. . ]+] ] ] ] ] ] ] ] ] ] -+..3 #.. J @+|+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] _+d + . F.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . ",
". . . . . . . . . t 1+Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] w.] ] ] ] ] ] ] ] ] ] ] ] ] 3 2+H + . ]+] ] ] ] ] ] ] ] ] ] 3 _+~ #.S 3+~ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] w.#.. F.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . ",
". . . . . . . . @ ;+3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] c U.. ]+] ] ] ] ] ] ] ] ] ] ] ] ] T E.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] x.k F.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . ",
". . . . . . . 5 4+Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] : f ]+] ] ] ] ] ] ] ] ] ] ] ] ] Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 2.=+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . ",
". . . . . . . Z c ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ ( ~+5+6+7+7+m.5+_ >.2 3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] -+++]+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 2 2+N.8+7+^+w |+~ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] _+{ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . ",
". . . . . . f -.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 2 b.9+0+f.+ . . . . . f a+= 4+b+{ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] &.]+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] [.c+d+= k 5 . . . 5 :.} e+c ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] { { { { { { ^ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 { { { { { { { { { { f+. . . . . . ",
". . . . . . R.[.] ] ] ] ] ] ] ] ] ] ] ] ] ] 3.`.f.. . . . . . . . . . . . . I B / ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j.g+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] { x.h+S . . . . . . . . . . 5 8.T.{ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 8+p.p.p.p.p.D 3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] M.p.p.p.p.p.p.p.p.p.p.:.. . . . . . ",
". . . . . . i+] ] ] ] ] ] ] ] ] ] ] ] ] ] >.<++ . . . . . . . . . . . . . . . e V.[.] ] ] ] ] ] ] ] ] ] ] ] ] ] g.|+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] { j+k+. . . . . . . . . . . . . . :.E.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] /+. . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . A.3+T.! 3 ] ] ] ] ] ] ] ] ] ] Q >++ . . . . . . . . . . . . . . . . . [ g+] ] ] ] ] ] ] ] ] ] ] ] ] ] ]+-+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Q |.5.. . . . . . . . . . . . . . . . @.l+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] [.z . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . 5 5.f.9.Z !.2.X.w c [.^ 3 ] ^+s . . . . . . . . . . . . . . . . . . 5 ;+] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] { j+f . . . . . . . . . . . . . . . . . . 4 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ a . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . s :.F ~.m+8.. . . . . . . . . . . . . . . . . . . . l ] ] ] ] ] ] ] ] ] ] ] ] ] ] Q ^ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] _ 9.. . . . . . . . . . . . . . . . . . . q =+] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 a.. . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^.. . . . . . . . . . . . . . . . . . . . A.n+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] p . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + y.D ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ~ l.. . . . . . . . . . . . . . . . . . . . + m.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + $.Z >+o+) i ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3.t . . . . . . . . . . . . . . . . . . . . . D.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e k+a.[+W.b.g+-+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ) + . . . . . . . . . . . . . . . . . . . . . p+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . 5 ; q+~.#+'+1 v c.^ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] '+. . . . . . . . . . . . . . . . . . . . . . #+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . h.$.a.e.;.b.2+3 3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] B.. . . . . . . . . . . . . . . . . . . . . . r+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . s k+p.r.P =+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] r.. . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . r s+3+1 { ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y.. . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . . . z.Z.N.[.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . . 5 & !+Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] c.( ] ] ] ] ] ] ] ] ] ] ] ] ] ] c.{ ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . . h.Y.=+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ >.g.p+g I.B.] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . s m+2 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 Q F.x.n.].=.` J s + . . %.] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . . 7./ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ ( w | 7.- r e . . . . . . . . . %.] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . . t+-+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Q 8+@+q f . . . . . . . . . . . . . . %.] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] }.. . . . . . . . . . . . . . . . . ",
". . . . + W ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 2+7.f.. . . . . . . . . . . . . . . . . L.] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y.. . . . . . . . . . . . . . . . . ",
". . . . ++c ] ] ] ] ] ] ] ] ] ] ] ] ] ] F.<++ . . . . . . . . . . . . . . . . . . u+] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . C.3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] b . . . . . . . . . . . . . . . . . ",
". . . . 7.^ ] ] ] ] ] ] ] ] ] ] ] ] ] ] #++ . . . . . . . . . . . . . . . . . . 5.^+] ] ] ] ] ] ] ] ] ] ] ] ] ] v Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . <+{ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ).. . . . . . . . . . . . . . . . . ",
". . . . d.] ] ] ] ] ] ] ] ] ] ] ] ] ] [.K.. . . . . . . . . . . . . . . . . . . y._ ] ] ] ] ] ] ] ] ] ] ] ] ] ] w./ ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . - [.] ] ] ] ] ] ] ] ] ] ] ] ] ] ).. . . . . . . . . . . . . . . . . ",
". . . 5 v+] ] ] ] ] ] ] ] ] ] ] ] ] ] / a+. . . . . . . . . . . . . . . . . . . _.^ ] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . - [.] ] ] ] ] ] ] ] ] ] ] ] ] ] ).. . . . . . . . . . . . . . . . . ",
". . . 5 N.] ] ] ] ] ] ] ] ] ] ] ] ] ] { % . . . . . . . . . . . . . . . . . . @ P ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . - [.] ] ] ] ] ] ] ] ] ] ] ] ] ] d.. . . . . . . . . . . . . . . . . ",
". . . 5 ' ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] e+5 . . . . . . . . . . . . . . . . e x 3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] -+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . 0+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] S.5 . . . . . . . . . . . . . . . . ",
". . . . E.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] -+1.. . . . . . . . . . . . . . . ; w+{ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 2 { ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . # Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] ..8.. . . . . . . . 5 O . . . . . . ",
". . . . u 3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] |+6.s . . . . . . . . . . . f <+S.^ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . S / ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 N.{+S . . s :.X ].x+~.. . . . . . ",
". . . . Z i ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] c.m N + . . . . . . . z.> -.2 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . e ..] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Q _+y+<.! c Q 3 ] %.. . . . . . ",
". . . . 5 b.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] / z+w+`.{+{+7.%.-.i 3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . . T.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] E.. . . . . . ",
". . . . . p.=+] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . . x ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ~+. . . . . . ",
". . . . . . w+{ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . . Z { ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] =+J . . . . . ",
". . . . . . f.%+{ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ..j+8 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . . f s.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] / A+. . . . . ",
". . . . . . . t , { ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 b.A e X.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . . . _.v ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ O.. . . . . ",
". . . . . . . . z (.w.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ~+Z.I . . & / ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . . . e H ~ ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 L . . . . . ",
". . . . . . . . . 5 0+o.[.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ ~+4+z.+ . . . J t.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] Y . . . . . . . . . . . . . . . . . . . . . . &.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] j . . . . . . . e H.]+3 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] w+. . . . . ",
". . . . . . . . . . . + U.u+_+[.] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] [.>.D.!.A.. . . . . . . H [.{ { { { { { { { { { { { { { { { { { { { { { { { { { C . . . . . . . . . . . . . . . . . . . . . . r+{ { { { { { { { { { { { { { { j . . . . . . . . . k+l h / ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 3 2 ]+H . . . . . ",
". . . . . . . . . . . . . . *.s+, b+~+w./ ] ] ] ] ] ] [.c ~+S.q.=.[ + . . . . . . . . . r 1.K K K K K K K K K K K K K K K K K K K K K K K K K K A+. . . . . . . . . . . . . . . . . . . . . . +.K K K K K K K K K K K K K K K B+. . . . . . . . . . . z * q.' G v ^ ] ] ] ] ] ] ~ _+~+5+C+Z.p.z . . . . . . ",
". . . . . . . . . . . . . . . . . s :.I.l.g [+> > > =.<+t+[ s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f 0.q 1.!.> > > {+H.= v.:.f . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};

261
src/ant-phone.c Normal file
View File

@ -0,0 +1,261 @@
/*
*
* ANT (ANT is Not a Telephone)
* Copyright 2002, 2003 Roland Stigge
*
* ISDN Telephone application for Linux and OSS
* (full duplex or multiple sound devices needed)
*
* Author: Roland Stigge, stigge@antcom.de
* Created: 2002-09-04 (got the idea already around christmas 2000)
*
* Tested with: Debian GNU/Linux
*
*
* Some basic ideas for this program are based on:
* * IVCALL, Copyright 2000 Lennart Poettering <lennart@poettering.de> (GPL)
*
* This program uses sources from:
* * g711.c (by Sun Microsystems, BSD like license) from SoX
*
* Used libraries:
* * libsndfile (Erik de Castro Lopo <erikd@zip.com.au>)
* * GTK+
*
* Contributors: see AUTHORS file
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
/* regular GNU system includes */
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
#include <string.h>
#include <math.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <sys/ioctl.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#include <sys/time.h>
#include <getopt.h> /* GNU extension: long options */
#include <sched.h>
#include <locale.h>
#include <libintl.h>
/* For debugging purposes */
#include <mcheck.h>
/* own header files */
#include "globals.h"
#include "isdn.h"
#include "sound.h"
#include "mediation.h"
#include "gtk.h"
#include "session.h"
#include "util.h"
#include "client.h"
#include "server.h"
int main(int argc, char *argv[]) {
struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"usage", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{"cleanup", no_argument, 0, 'r'},
{"debug", optional_argument, 0, 'd'},
{"soundin", required_argument, 0, 'i'},
{"soundout", required_argument, 0, 'o'},
{"msn", required_argument, 0, 'm'},
{"msns", required_argument, 0, 'l'},
{"call", required_argument, 0, 'c'},
{0, 0, 0, 0}
};
char *short_options = "hvrd::i:o:m:l:c:";
int option_index = 0;
int c;
/* temporary default values = "", will be changed by command line options
and options in options file */
char *audio_device_name_in = "";
char *audio_device_name_out = "";
char *msn = "";
char *msns = "";
int gtk_result;
#ifdef DEBUG
mtrace();
debug = DEBUG;
#endif
/* prepare for i18n */
#ifdef ENABLE_NLS
setlocale(LC_ALL, "");
if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
fprintf(stderr, "Error setting directory for textdomain (i18n).\n");
}
output_codeset_save();
if (!textdomain(PACKAGE)) {
fprintf(stderr, "Error setting domainname for gettext() "
"(internationalization).\n");
}
#endif
/* only useful for yet to code separate audio thread
(rt only for audio thread!)
struct sched_param schedpar; // scheduler structure for priority
int priority_min, priority_max;
// linux realtime scheduling
if ((priority_min = sched_get_priority_min(SCHED_FIFO)) < 0) {
perror("Realtime scheduling setup");
exit(1);
}
if ((priority_max = sched_get_priority_max(SCHED_FIFO)) < 0) {
perror("Realtime scheduling setup");
exit(1);
}
schedpar.sched_priority = (priority_min + priority_max) / 2; // arbitrary
if (sched_setscheduler(0, SCHED_FIFO, &schedpar) < 0) {
perror("Activating realtime scheduler");
}
// give up root privileges
if (setuid(getuid()) < 0) {
perror("Giving up root privileges");
}
*/
/* first: GTK+ internal parsing of command line arguments */
gtk_init(&argc, &argv);
/* parse command line options */
while ((c = getopt_long(argc, argv, short_options, long_options,
&option_index)) != -1) {
switch(c) {
case 'h': /* help */
printf(_("Usage: %s [OPTION...]\n\
\n\
Options:\n\
-h, --help Show this help message\n\
-v, --version Print version information\n\
-r, --cleanup Remove stale socket file (left by accident by\n\
previous run)\n\
-d, --debug[=level] Print additional runtime debugging data to stdout\n\
level = 1..2\n\
-i, --soundin=DEVICE OSS compatible device for input (recording),\n\
default: /dev/dsp\n\
-o, --soundout=DEVICE OSS compatible device for output (playback),\n\
default: /dev/dsp\n\
-m, --msn=MSN identifying MSN (for outgoing calls), 0 for master\n\
MSN of this termination/port\n\
default: 0\n\
-l, --msns=MSNS MSNs to listen on, semicolon-separated list or '*'\n\
default: *\n\
-c, --call=NUMBER Call specified number\n\
\n\
Note: If arguments of --soundin and --soundout are equal, a full duplex\n\
sound device is needed.\n"), argv[0]);
exit(0);
case 'v': /* version */
printf("ANT " VERSION "\n");
exit(0);
case 'r': /* clean up: remove old locking files */
if (-1 == unlink(server_local_socket_name())) {
perror("unlink old socket file");
}
break;
case 'd': /* debug mode */
if (optarg) {
debug = strtol(optarg, NULL, 0);
} else {
debug = 1;
}
break;
case 'i': /* sound input device */
audio_device_name_in = optarg;
break;
case 'o': /* sound output device */
audio_device_name_out = optarg;
break;
case 'm': /* identifying msn */
msn = optarg;
break;
case 'l': /* msns to listen on, '*' or semicolon-separated list */
msns = optarg;
break;
case 'c':
printf(_("Calling %s... "), optarg);
if (client_make_call(optarg)) {
printf("\nAn error occured while calling a running " PACKAGE ".\n");
} else {
printf(_("successful.\n"));
}
exit(0);
break;
case '?':
exit(1);
}
}
/* no further arguments expected, so not handled */
output_codeset_set("UTF-8"); /* GTK needs UTF-8 strings */
if (session_init(&session, audio_device_name_in, audio_device_name_out,
msn, msns))
{
fprintf(stderr, "Error at session init.\n");
exit(1);
} else {
if (debug)
fprintf(stderr, "Init OK.\n");
}
/* gtk stuff, main loop */
gtk_result = main_gtk(&session);
if (session_deinit(&session)) {
fprintf(stderr, "Error at session exit\n");
exit(1);
} else {
if (debug)
fprintf(stderr, "Quit OK.\n");
}
output_codeset_set(NULL); /* restore saved codeset */
return gtk_result;
}

14
src/backspace.xpm Normal file
View File

@ -0,0 +1,14 @@
/* XPM */
static char * backspace_xpm[] = {
"14 9 2 1",
" c None",
". c #000000",
" . ",
" .. ",
" ... ",
" .............",
"..............",
" .............",
" ... ",
" .. ",
" . "};

926
src/callerid.c Normal file
View File

@ -0,0 +1,926 @@
/*
* caller id related functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
/* regular GNU system includes */
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <glob.h>
#include <fcntl.h>
/* GTK */
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
/* own header files */
#include "globals.h"
#include "callerid.h"
#include "session.h"
#include "util.h"
#include "isdn.h"
/* graphical symbols */
#include "in.xpm"
#include "out.xpm"
#include "record.xpm"
/*
* returns a new data structure (for association with a row)
* filled with default values
*/
static gpointer cid_row_new(void) {
struct cid_row_t *rowdata =
(struct cid_row_t *) malloc(sizeof(struct cid_row_t));
rowdata->marked_unanswered = 0;
return (gpointer) rowdata;
}
/*
* callback to be called for additional row data on destruction of row
*/
static void cid_row_destroy(gpointer rowdata) {
if (debug > 1)
fprintf(stderr, "debug: destroying rowdata at %p.\n", rowdata);
free(rowdata);
}
/* called when caller id monitor state check button is toggled */
void cid_toggle_cb(GtkWidget *widget _U_, gpointer data, guint action _U_) {
session_t *session = (session_t *) data;
if (GTK_CHECK_MENU_ITEM (session->cid_check_menu_item)->active) {
gtk_widget_show(session->cid);
session->option_show_callerid = 1;
} else {
gtk_widget_hide(session->cid);
session->option_show_callerid = 0;
gtk_window_resize(GTK_WINDOW(session->main_window), 1, 1);
}
}
/*
* Callback: called when a button was clicked in row delete dialog
*/
static void cid_delete_response_cb(GtkWidget* widget, gint response_id,
gpointer data)
{
session_t* session = (session_t*) data;
guint row = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "row"));
char* filename = (char*) g_object_get_data(G_OBJECT(widget), "filename");
GtkWidget* checkbutton =
(GtkWidget*) g_object_get_data(G_OBJECT(widget), "checkbutton");
if (response_id == GTK_RESPONSE_OK) {
if (filename &&
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton)))
{
unlink(filename);
}
cid_mark_row(session, row, FALSE); /* to count unanswered calls */
session->cid_num--;
/* decrease before removal: "select-row" signal submission -> other cb */
gtk_clist_remove(GTK_CLIST(session->cid_list), row);
}
if (filename) free(filename);
gtk_widget_destroy(widget);
}
/*
* called on cid delete request
*
* -> deletes specified row without confirmation
*/
static void cid_request_delete(GtkWidget *widget _U_, gpointer data,
guint row) {
session_t* session = (session_t *) data;
GtkWidget* vbox;
GtkWidget* label;
GtkWidget* checkbutton;
char *filename = cid_get_record_filename(session, row);
GtkWidget* dialog = gtk_dialog_new_with_buttons(_("Delete Entry"),
GTK_WINDOW(session->main_window),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL);
vbox = gtk_vbox_new(FALSE, 16);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 16);
gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox);
gtk_widget_show(vbox);
label = gtk_label_new(_("Are you sure you want to\ndelete this entry?"));
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
gtk_box_pack_start_defaults(GTK_BOX(vbox), label);
gtk_widget_show(label);
checkbutton = gtk_check_button_new_with_label(_("Delete recording"));
if (filename) { /* default: checked */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE);
} else { /* if file doesn't exist, grey out */
gtk_widget_set_sensitive(checkbutton, FALSE);
}
gtk_box_pack_start_defaults(GTK_BOX(vbox), checkbutton);
gtk_widget_show(checkbutton);
g_object_set_data(G_OBJECT(dialog), "row", GUINT_TO_POINTER(row));
g_object_set_data(G_OBJECT(dialog), "filename", (gpointer) filename);
g_object_set_data(G_OBJECT(dialog), "checkbutton", (gpointer) checkbutton);
g_signal_connect(dialog, "response", G_CALLBACK(cid_delete_response_cb),
session);
gtk_widget_show(dialog);
}
/*
* called on key pressed in cid list
*/
static gint cid_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) {
switch (event->keyval) {
case GDK_Delete: /* Delete dialog */
case GDK_KP_Delete:
/* portability: GtkCList.selection is private! */
if (GTK_CLIST(((session_t *) data)->cid_list)->selection) {
cid_request_delete(widget, data,
GPOINTER_TO_INT(GTK_CLIST(((session_t *) data)->cid_list)->selection->data));
}
return TRUE; /* event handled */
default:
return FALSE;
}
}
/*
* Callback: called on playback request
*/
static void cid_playback(GtkWidget *widget _U_, gpointer data, guint row) {
session_t *session = (session_t *) data;
session->effect_filename = cid_get_record_filename(session, row);
session->effect_playback_start_time = time(NULL);
session_set_state(session, STATE_PLAYBACK);
}
/*
* Callback: called on "OK" click in "Save as..." file selection
*/
static void cid_save_as_filename_cb(GtkWidget *fs) {
char* sourcename = g_object_get_data(G_OBJECT(fs), "sourcename");
const char* destbase =
gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs));
if (*destbase && *basename(destbase)) {
/* copy if something was entered */
char* destination;
char* extension = filename_extension(sourcename);
if (0 <= asprintf(&destination, "%s.%s", destbase, extension)) {
/* actually copy if source and destination known */
int buffer_size = 65536;
char* buffer = (char*) malloc(buffer_size);
if (buffer) {
int fd_in = open(sourcename, O_RDONLY);
if (fd_in != -1) {
int fd_out = open(destination, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
if (fd_out != -1) {
int just_read;
do {
int to_write = just_read = read(fd_in, buffer, buffer_size);
int written = 1;
char* buffer_index = buffer;
while (to_write && written) {
written = write(fd_out, buffer_index, to_write);
to_write -= written;
buffer_index += written;
}
} while (just_read);
if (close(fd_out)) {
fprintf(stderr, "Error on closing destination file.\n");
}
} else {
fprintf(stderr,
"Error on destination file (%s) open().\n", destination);
}
if (close(fd_in)) {
fprintf(stderr, "Error on source file.\n");
}
} else {
fprintf(stderr,
"Error on source file (%s) open().\n", sourcename);
}
free(buffer);
} else {
fprintf(stderr, "Error on malloc().\n");
}
free(destination);
} else {
fprintf(stderr, "Error on asprintf().\n");
}
}
free(sourcename);
gtk_widget_destroy(GTK_WIDGET(fs));
}
/*
* Callback: called on "Save as..." request
*/
static void cid_save_as(GtkWidget *widget _U_, gpointer data, guint row) {
session_t* session = (session_t*) data;
char* sourcename = cid_get_record_filename(session, row);
char* extension = filename_extension(sourcename);
if (extension) {
GtkWidget* fs;
char* title;
if (0 > asprintf(&title, _("Enter the base filename for %s file"),
extension))
{
fprintf(stderr, "Error on asprintf().\n");
return;
}
fs = gtk_file_selection_new(title);
free(title);
g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(fs)->cancel_button),
"clicked", G_CALLBACK(gtk_widget_destroy),
(gpointer) fs);
g_object_set_data(G_OBJECT(fs), "sourcename", sourcename);
g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
"clicked", G_CALLBACK(cid_save_as_filename_cb), fs);
gtk_widget_show(fs);
} else {
fprintf(stderr, "Error: no filename extension found.\n");
}
}
/*
* Callback: called if something happened in the delete recording dialog
*/
static void cid_delete_rec_response_cb(GtkWidget* widget, gint response_id,
gpointer data)
{
session_t *session = (session_t *) data;
if (response_id == GTK_RESPONSE_OK) {
char* temp;
guint row = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "row"));
unlink(temp = cid_get_record_filename(session, row));
free(temp);
cid_row_mark_record(session, row);
}
gtk_widget_destroy(widget);
}
/*
* Callback: called on delete recording request
*/
static void cid_delete_rec(GtkWidget *widget _U_, gpointer data, guint row) {
session_t *session = (session_t *) data;
GtkWidget* dialog = gtk_message_dialog_new(GTK_WINDOW(session->main_window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING,
GTK_BUTTONS_OK_CANCEL, _("Do you really want to delete this recording?"));
g_signal_connect(dialog, "response", G_CALLBACK(cid_delete_rec_response_cb),
session);
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
g_object_set_data(G_OBJECT(dialog), "row", GINT_TO_POINTER(row));
gtk_widget_show(dialog);
}
/*
* called on mouse button pressed in cid list
*/
static gint cid_mouse_cb(GtkWidget *widget _U_,
GdkEventButton *event, gpointer data) {
session_t *session = (session_t *) data;
if (event->button == 3) { /* popup menu */
gint row;
gint column;
if (gtk_clist_get_selection_info(GTK_CLIST(session->cid_list),
event->x, event->y, &row, &column)) {
GtkItemFactoryEntry menu_items[] = {
/*path accel. callb. cb param. kind extra */
{_("/_Playback"), NULL, cid_playback, row, "", NULL},
{_("/_Save as..."), NULL, cid_save_as, row, "", NULL},
{_("/Delete _Recording"),NULL, cid_delete_rec,row, "", NULL},
{ "/Sep", NULL, NULL, 0, "<Separator>", NULL},
{_("/_Delete Row"), NULL, cid_request_delete, row, "", NULL}
};
GtkMenu *menu = GTK_MENU(gtk_menu_new());
GtkItemFactory *item_factory;
GtkAccelGroup *accel_group;
gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
GtkWidget *playback_item;
GtkWidget *save_as_item;
GtkWidget *delete_record_item;
GtkWidget *delete_item;
char* fn;
char* temp;
accel_group = gtk_accel_group_new();
item_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<popup>",
accel_group);
gtk_item_factory_create_items_ac(item_factory, nmenu_items, menu_items,
session, 2);
if (!(playback_item = gtk_item_factory_get_item(item_factory,
temp = stripchr(_("/_Playback"), '_'))))
fprintf(stderr, "Error getting playback_item.\n");
free(temp);
if (!(save_as_item = gtk_item_factory_get_item(item_factory,
temp = stripchr(_("/_Save as..."), '_'))))
fprintf(stderr, "Error getting save_as_item.\n");
free(temp);
if (!(delete_record_item = gtk_item_factory_get_item(item_factory,
temp = stripchr(_("/Delete _Recording"), '_'))))
fprintf(stderr, "Error getting delete_record_item_item.\n");
free(temp);
if (!(delete_item = gtk_item_factory_get_item(item_factory,
temp = stripchr(_("/_Delete Row"), '_'))))
fprintf(stderr, "Error getting delete_item.\n");
free(temp);
if (!(session->state == STATE_READY &&
(fn = cid_get_record_filename(session, row)))) {
gtk_widget_set_sensitive(playback_item, FALSE);
gtk_widget_set_sensitive(save_as_item, FALSE);
gtk_widget_set_sensitive(delete_record_item, FALSE);
} else {
free(fn);
}
menu = GTK_MENU(gtk_item_factory_get_widget(item_factory, "<popup>"));
gtk_menu_set_accel_group(menu, accel_group);
gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button, event->time);
}
return TRUE; /* event handled */
} else {
return FALSE;
}
}
/*
* called on row select (to unmark lines)
*/
static void cid_select_row_cb(GtkCList *list _U_, gint row, gint column _U_,
GdkEventButton *button _U_, gpointer data) {
session_t *session = (session_t *) data;
if (row < session->cid_num)
cid_mark_row(session, row, FALSE);
}
/*
* Returns the Caller ID section as GtkWidget,
* sets CID related members in session
* NOTE: caller has to gtk_widget_show() this widget
*/
GtkWidget *cid_new(session_t *session) {
GtkWidget *frame; /* frame with comment */
GtkWidget *scrolled_window; /* the home for the clist */
GtkWidget *clist; /* the list itself */
GtkStyle *style; /* needed for preparing symbols */
GtkWidget *pixmapwidget; /* record symbol */
gchar *titles[CID_COL_NUMBER];
style = gtk_widget_get_style(session->main_window);
frame = gtk_frame_new(_("Caller ID"));
titles[CID_COL_FLAGS ] = "";
titles[CID_COL_TIME ] = _("Date/Time");
titles[CID_COL_TYPE ] = _("Type");
titles[CID_COL_FROM ] = _("From");
titles[CID_COL_TO ] = _("To");
titles[CID_COL_DURATION] = _("Duration");
gtk_container_set_border_width(GTK_CONTAINER(frame), 8);
/* the scrolled window: no special adjustments */
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
/* always vertical scroll bar, horizontal... well... automatic means no ;) */
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
gtk_container_add(GTK_CONTAINER(frame), scrolled_window);
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 8);
gtk_widget_show(scrolled_window);
/* the list widget */
clist = gtk_clist_new_with_titles(CID_COL_NUMBER, titles);
session->symbol_record_pixmap = gdk_pixmap_create_from_xpm_d(
session->main_window->window,
&session->symbol_record_bitmap,
&style->bg[GTK_STATE_NORMAL],
(gchar **) record_xpm);
pixmapwidget = gtk_pixmap_new(session->symbol_record_pixmap,
session->symbol_record_bitmap);
gtk_clist_set_column_widget(GTK_CLIST(clist), CID_COL_FLAGS, pixmapwidget);
/* default: GTK_SELECTION_MULTIPLE: */
gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_BROWSE);
gtk_clist_set_shadow_type(GTK_CLIST(clist), GTK_SHADOW_IN);
gtk_clist_set_column_width(GTK_CLIST(clist), CID_COL_FLAGS, 14);
gtk_clist_set_column_width(GTK_CLIST(clist), CID_COL_TIME, 128);
gtk_clist_set_column_width(GTK_CLIST(clist), CID_COL_TYPE, 30);
gtk_clist_set_column_width(GTK_CLIST(clist), CID_COL_FROM, 100);
gtk_clist_set_column_width(GTK_CLIST(clist), CID_COL_TO, 100);
gtk_clist_set_column_width(GTK_CLIST(clist), CID_COL_DURATION, 80);
/*gtk_clist_set_column_width(GTK_CLIST(clist), 5, 80);*/
gtk_container_add(GTK_CONTAINER(scrolled_window), clist);
gtk_clist_column_titles_show(GTK_CLIST(clist));
gtk_widget_set_size_request(clist, 500, 128);
gtk_signal_connect(GTK_OBJECT(clist), "key-press-event",
GTK_SIGNAL_FUNC(cid_key_cb), session);
gtk_signal_connect(GTK_OBJECT(clist), "button-press-event",
GTK_SIGNAL_FUNC(cid_mouse_cb), session);
gtk_signal_connect(GTK_OBJECT(clist), "select-row",
GTK_SIGNAL_FUNC(cid_select_row_cb), session);
gtk_widget_show(clist);
/* set up IN/OUT symbols */
session->symbol_in_pixmap = gdk_pixmap_create_from_xpm_d(
session->main_window->window,
&session->symbol_in_bitmap,
&style->bg[GTK_STATE_NORMAL],
(gchar **) in_xpm);
session->symbol_out_pixmap = gdk_pixmap_create_from_xpm_d(
session->main_window->window,
&session->symbol_out_bitmap,
&style->bg[GTK_STATE_NORMAL],
(gchar **) out_xpm);
session->cid = frame;
session->cid_list = clist;
session->cid_scrolled_window = scrolled_window;
return frame;
}
/*
* select last item in cid list and adjust view to end of list
*/
void cid_jump_to_end(session_t *session) {
GtkAdjustment *adj;
gtk_clist_select_row(GTK_CLIST(session->cid_list),
session->cid_num - 1, 0);
adj = gtk_scrolled_window_get_vadjustment(
GTK_SCROLLED_WINDOW(session->cid_scrolled_window));
gtk_adjustment_set_value(adj, fmax(adj->lower, adj->upper - adj->page_size));
}
/*
* remove unneeded entries from caller id list (shorten log)
*/
void cid_normalize(session_t *session) {
while (session->cid_num_max && session->cid_num > session->cid_num_max) {
gtk_clist_remove(GTK_CLIST(session->cid_list), 0);
session->cid_num--;
}
}
/*
* returns a dynamically allocated string in cid conformant time format
* caller has got to take care of freeing this memory after usage
*/
static char *cid_timestring(time_t t) {
char *date = (char *) malloc(20);
int len;
date[0] = '\1';
len = strftime(date, 20, "%Y-%m-%d %H:%M:%S", localtime(&t));
if (len == 0 && date[0] != '\0') {
fprintf(stderr, "cid: Error calculating time with strftime.\n");
return NULL;
}
return date;
}
/*
* insert new entry at end of list
*
* from == NULL, if still unknown
*/
void cid_add_line(session_t *session,
enum call_type_t ct, gchar *from, gchar *to) {
gchar *line[CID_COL_NUMBER];
char *typestring;
GdkPixmap *pixmap;
GdkBitmap *bitmap;
/* First: date */
line[CID_COL_TIME] = cid_timestring(session->ring_time);
line[CID_COL_FLAGS] = "";
line[CID_COL_TYPE] = ""; /* call type */
if (from == NULL) /* the from field */
line[CID_COL_FROM] = "???";
else
line[CID_COL_FROM] = from;
line[CID_COL_TO] = to;
line[CID_COL_DURATION] = "???"; /* duration */
/* create line */
session->cid_num = gtk_clist_append(GTK_CLIST(session->cid_list), line) + 1;
gtk_clist_set_row_data_full(GTK_CLIST(session->cid_list),
session->cid_num - 1,
cid_row_new(), cid_row_destroy);
cid_normalize(session);
/* actually set pixmap */
if (ct == CALL_IN) {
pixmap = session->symbol_in_pixmap;
bitmap = session->symbol_in_bitmap;
typestring = "IN";
} else {
pixmap = session->symbol_out_pixmap;
bitmap = session->symbol_out_bitmap;
typestring = "OUT";
}
gtk_clist_set_pixtext(GTK_CLIST(session->cid_list), session->cid_num - 1 ,
CID_COL_TYPE, typestring, 50, pixmap, bitmap);
cid_jump_to_end(session);
/* clean up */
free(line[CID_COL_TIME]);
}
/*
* set "date" field in last line
*/
void cid_set_date(session_t *session, time_t date) {
if (date) {
char *temp;
gtk_clist_set_text(GTK_CLIST(session->cid_list),
session->cid_num - 1, CID_COL_TIME,
temp = cid_timestring(date));
free(temp);
}
}
/*
* set "from" field in last line
*/
void cid_set_from(session_t *session, gchar *from) {
if (from)
gtk_clist_set_text(GTK_CLIST(session->cid_list),
session->cid_num - 1, CID_COL_FROM, from);
}
/*
* complete last line with "duration"
*
* if message == NULL, current time will be used to calculate a duration
* if message != NULL, this string will be displayed in the Duration field (#4)
*/
void cid_set_duration(session_t *session, gchar *message) {
char *buf = timediff_str(time(NULL), session->vcon_time);
if (message)
gtk_clist_set_text(GTK_CLIST(session->cid_list), session->cid_num - 1,
CID_COL_DURATION, message);
else
gtk_clist_set_text(GTK_CLIST(session->cid_list), session->cid_num - 1,
CID_COL_DURATION, buf);
free(buf);
}
/*
* Add a line to clist (e.g. from saved caller id file)
*/
void cid_add_saved_line(session_t *session, char *date, char *type,
char *from, char *to, char *duration) {
if (debug > 1)
fprintf(stderr, "Caller ID add:\n"
"Date: |%s|, Type: |%s|, From: |%s|, To: |%s|, Dur: |%s|\n",
date, type, from, to, duration);
cid_add_line(session,
!strncmp(type, "IN", 2) ? CALL_IN : CALL_OUT, from, to);
gtk_clist_set_text(GTK_CLIST(session->cid_list),
session->cid_num - 1, CID_COL_TIME, date);
gtk_clist_set_text(GTK_CLIST(session->cid_list),
session->cid_num - 1, CID_COL_DURATION, duration);
cid_row_mark_record(session, session->cid_num - 1);
}
/*
* Merges isdnlog data into existing cid list
*/
void cid_calls_merge(session_t *session) {
int low, high, mid; /* bounds and helper index */
time_t start = time(NULL)
- 60 * 60 * 24 * session->option_calls_merge_max_days;
int callstime; /* time of calls file line */
char *cidstr; /* time of cid_list entry */
size_t linelength = 100; /* buffer size */
char *line = (char *) malloc (linelength); /* initial buffer for getline() */
FILE *f = NULL;
char from[41]; /* data to read from calls file */
char to[41];
int duration;
int date;
char type[4];
char *temp;
int rel;
int cidline; /* index into cid list */
gchar *linearr[CID_COL_NUMBER]; /* line to insert to cid_list */
GdkPixmap *pixmap;
GdkBitmap *bitmap;
char *cache; /* tracks successive dates */
char* calls_filename;
/* try to find isdnlog data file */
calls_filename = isdn_get_calls_filename();
if (calls_filename && (f = fopen(calls_filename, "r"))) {
if (debug) {
fprintf(stderr, "Using %s as source for isdnlog data.\n", calls_filename);
}
if (session->option_calls_merge_max_days) {
/* binary search on the file for the desired starting time if needed */
if (debug >= 3) {
fprintf(stderr, "Binary search in calls file...\n");
}
low = 0;
fseek(f, 0, SEEK_END);
high = ftell(f);
while (high - low > 200) {
if (debug >= 3) {
fprintf(stderr, "low = %d, high = %d\n", low, high);
}
mid = (low + high) / 2;
fseek(f, mid, SEEK_SET);
getline(&line, &linelength, f); /* discard potentially partial line */
if (-1 != getline(&line, &linelength, f)) {
if (!sscanf(line, "%*40[^|]|%*40[^|]|%*40[^|]|%*40[^|]|%*40[^|]|%d",
&callstime))
break;
if (callstime < start)
low = mid;
else
high = mid;
} else
break;
}
fseek(f, low, SEEK_SET);
getline(&line, &linelength, f);
}
/* read in all remaining lines: merge */
cidline = 0;
cache = strdup("");
while (!feof(f)) {
/* get new calls line */
if (-1 == getline(&line, &linelength, f)) break;
if (sscanf(line,
"%*40[^|]|%40[^|]|%40[^|]|%d|%*40[^|]|%d|%*40[^|]|%1c",
from, to, &duration, &date, type) != 5) {
fprintf(stderr, "Warning: Incomplete data input from calls file.\n");
break;
}
if ((temp = strchr(from, ' '))) *temp = '\0';
if ((temp = strchr(to, ' '))) *temp = '\0';
if (type[0] == 'I') {
type[1] = 'N';
type[2] = '\0';
pixmap = session->symbol_in_pixmap;
bitmap = session->symbol_in_bitmap;
} else {
type[1] = 'U';
type[2] = 'T';
type[3] = '\0';
pixmap = session->symbol_out_pixmap;
bitmap = session->symbol_out_bitmap;
}
/* prepare (text) line to merge */
linearr[CID_COL_TIME] = cid_timestring((time_t)date);
linearr[CID_COL_TYPE] = type;
if (*from)
linearr[CID_COL_FROM] = from;
else
linearr[CID_COL_FROM] = "???";
if (*to)
linearr[CID_COL_TO] = to;
else
linearr[CID_COL_TO] = "???";
if (duration < 0) {
linearr[CID_COL_DURATION] = strdup(_("(UNKNOWN)"));
} else {
linearr[CID_COL_DURATION] = timediff_str(duration, (time_t) 0);
}
/* where to merge it in? */
rel = 1; /* init to merge by default */
while (cidline < session->cid_num &&
(gtk_clist_get_text(GTK_CLIST(session->cid_list),
cidline, CID_COL_TIME, &cidstr),
(rel = strcmp(cidstr, linearr[CID_COL_TIME])) < 0)) {
cidline++;
}
if ((rel > 0 && strcmp(linearr[CID_COL_TIME], cache) > 0)
|| cidline == session->cid_num) {
/* only merge new and successive entries */
gtk_clist_insert(GTK_CLIST(session->cid_list), cidline, linearr);
gtk_clist_set_row_data_full(GTK_CLIST(session->cid_list), cidline,
cid_row_new(), cid_row_destroy);
gtk_clist_set_pixtext(GTK_CLIST(session->cid_list),
cidline, CID_COL_TYPE, type, 50, pixmap, bitmap);
session->cid_num++;
}
free(cache);
cache = linearr[CID_COL_TIME];
free(linearr[CID_COL_DURATION]);
}
free(cache);
cid_normalize(session);
if (fclose(f))
fprintf(stderr, "Error closing %s.\n", calls_filename);
} else { /* error on fopen() */
fprintf(stderr,
"Warning: Couldn't open isdnlog calls logfile. Proceeding without it.\n");
}
free(line);
}
/*
* - marks caller id row as unanswered
* - sets window title to reflect number of unanswered calls
*
* input: session
* row number of specified row
* state 1 for mark, 0 for unmark
*/
void cid_mark_row(session_t *session, int row, int state) {
struct cid_row_t *rowdata = (struct cid_row_t *) gtk_clist_get_row_data(
GTK_CLIST(session->cid_list), row);
GdkColor color;
char *title;
if (rowdata->marked_unanswered != state) {
if (state) {
gdk_color_parse("#FF8888", &color);
session->unanswered++;
rowdata->marked_unanswered = 1;
} else {
gdk_color_parse("#FFFFFF", &color);
session->unanswered--;
rowdata->marked_unanswered = 0;
}
gtk_clist_set_background(GTK_CLIST(session->cid_list), row, &color);
if (session->unanswered
&& 0 < asprintf(&title, _("ANT: %d unanswered"), session->unanswered)) {
gtk_window_set_title(GTK_WINDOW(session->main_window), title);
free(title);
} else {
gtk_window_set_title(GTK_WINDOW(session->main_window), "ANT " VERSION);
}
}
}
/*
* returns timestring with just digits
* - caller has got to free() the result
*/
char* cid_purify_timestring(char *s) {
char* t;
int length = 0;
char* result;
char* result_index;
for (t=s; *t; t++) {
if (isdigit (*t))
length++;
}
result_index = result = (char*) malloc (length + 1);
for (t=s; *t; t++) {
if (isdigit (*t)) {
*(result_index++) = *t;
}
}
*(result_index++) = '\0';
return result;
}
/*
* returns name of sound filename, if it exists; NULL otherwise
* - caller has go to free() result
*/
char* cid_get_record_filename(session_t* session, int row) {
char* timestr;
char* homedir;
char* pattern;
glob_t g;
char* result; /* found something */
gtk_clist_get_text(GTK_CLIST(session->cid_list), row, CID_COL_TIME, &timestr);
timestr = cid_purify_timestring(timestr);
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return NULL;
}
if (asprintf(&pattern, "%s/." PACKAGE "/recordings/%s.*",
homedir, timestr) < 0) {
fprintf(stderr, "Warning: "
"Couldn't allocate memory for filename globbing pattern.\n");
return NULL;
}
switch (glob(pattern, 0, NULL, &g)) {
case 0:
result = strdup(*(g.gl_pathv));
break;
case GLOB_NOMATCH:
result = NULL;
break;
default:
fprintf(stderr, "Warning: "
"globbing error while looking up recorded conversation.\n");
return NULL;
}
globfree(&g);
free(pattern);
free(timestr);
return result;
}
/*
* marks row with record sign if recording available
* - deletes mark if recording was removed before
*/
void cid_row_mark_record(session_t* session, int row) {
char* fn;
if ((fn = cid_get_record_filename(session, row))) {
gtk_clist_set_pixmap(GTK_CLIST(session->cid_list), row, CID_COL_FLAGS,
session->symbol_record_pixmap, session->symbol_record_bitmap);
free(fn);
} else {
gtk_clist_set_text(GTK_CLIST(session->cid_list), row, CID_COL_FLAGS, "");
}
}

72
src/callerid.h Normal file
View File

@ -0,0 +1,72 @@
/*
* caller id related functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* GTK */
#include <gtk/gtk.h>
/* own header files */
#include "session.h"
enum call_type_t {
CALL_IN,
CALL_OUT
};
/*
* (Sequential) positions of columns (order)
*/
enum cid_col_t {
CID_COL_FLAGS,
CID_COL_TIME,
CID_COL_TYPE,
CID_COL_FROM,
CID_COL_TO,
CID_COL_DURATION,
/*XXX, "Zone" */
CID_COL_NUMBER /* for calculating size */
};
/*
* _additional_ (invisible) data associated with a row
*/
struct cid_row_t {
int marked_unanswered;
};
void cid_toggle_cb(GtkWidget *widget, gpointer data, guint action);
GtkWidget *cid_new(session_t *session);
void cid_add_line(session_t *session,
enum call_type_t ct, gchar *from, gchar *to);
void cid_set_date(session_t *session, time_t date);
void cid_set_from(session_t *session, gchar *from);
void cid_set_duration(session_t *session, gchar *message);
void cid_jump_to_end(session_t *session);
void cid_normalize(session_t *session);
void cid_add_saved_line(session_t *session, char *date, char *type,
char *from, char *to, char *duration);
void cid_calls_merge(session_t *session);
void cid_mark_row(session_t *session, int row, int state);
char* cid_get_record_filename(session_t* session, int row);
void cid_row_mark_record(session_t* session, int row);

92
src/calleridlexer.l Normal file
View File

@ -0,0 +1,92 @@
%option prefix="callerid_"
%option nounput
%{
/*
* saved caller id file lexer
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#define YYSTYPE char *
#include <string.h>
#include "globals.h"
#include "calleridparser.h"
YYLTYPE callerid_lloc;
void callerid_locate();
%}
LETTER [a-zA-Z]
DIGIT [0-9]
NOEM {LETTER}|{DIGIT}|[-:)(*#]
%%
"|"|!! callerid_locate(); return CID_TOKEN_DELIMITER;
{DIGIT}+-{DIGIT}+-{DIGIT}+" "{DIGIT}+:{DIGIT}+:{DIGIT}+ {
callerid_locate();
callerid_lval = strdup(callerid_text);
return CID_TOKEN_DATE;
}
IN|OUT {
callerid_locate();
callerid_lval = strdup(callerid_text);
return CID_TOKEN_TYPE;
}
({DIGIT}|[*#+?A-D])+ {
callerid_locate();
callerid_lval = strdup(callerid_text);
return CID_TOKEN_NUMBER;
}
(!?{NOEM}+)+!? {
callerid_locate();
callerid_lval = strdup(callerid_text);
return CID_TOKEN_MSG;
}
\n callerid_locate(); return *callerid_text;
. callerid_locate();
/* eat up rest (handled as white space) */
%%
/* For portability's sake */
int callerid_wrap() { return 1; }
/*
* adjusts callerid_lloc according to callerid_text
*/
void callerid_locate() {
char* temp;
callerid_lloc.first_line = callerid_lloc.last_line;
callerid_lloc.first_column = callerid_lloc.last_column;
for (temp = yytext; *temp != '\0'; temp++) {
if (*temp == '\n') {
++ callerid_lloc.last_line;
callerid_lloc.last_column = 1;
} else {
++ callerid_lloc.last_column;
}
}
}

86
src/calleridparser.y Normal file
View File

@ -0,0 +1,86 @@
%name-prefix="callerid_"
%{
/*
* saved callerid file parser
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* type for semantic values of symbols: malloc'ed strings */
#define YYSTYPE char*
/* let yyparse() accept one argument of type void * */
#define YYPARSE_PARAM session
/* regular GNU system includes */
#include <stdio.h>
#include <stdlib.h>
/* own header files */
#include "globals.h"
#include "util.h"
#include "callerid.h"
int callerid_lex (void);
void callerid_error(const char *message);
%}
/* terminal symbols */
%token CID_TOKEN_DATE
%token CID_TOKEN_TYPE
%token CID_TOKEN_NUMBER
%token CID_TOKEN_MSG
%token CID_TOKEN_DELIMITER
%%
settings :
| settings line
;
line : '\n'
| CID_TOKEN_DATE CID_TOKEN_DELIMITER
CID_TOKEN_TYPE CID_TOKEN_DELIMITER
CID_TOKEN_NUMBER CID_TOKEN_DELIMITER
CID_TOKEN_NUMBER CID_TOKEN_DELIMITER
CID_TOKEN_MSG '\n'
{ cid_add_saved_line(session, $1, $3, $5, $7, $9);
free($1); free($3); free($5); free($7); free($9); }
| error '\n'
{ if (debug)
fprintf(stderr,
"Warning: Parsing callerid history file:%d, "
"recovering after error.\n", @1.last_line);
}
;
%%
/*
* callback for yyparse(), (also) called on errors (hopefully) handled
* by error token actions in grammar, but not if errors occur to
* often (bison needs 3 "correct" tokens to recover)
*/
void callerid_error(const char *message) {
if (debug)
fprintf(stderr,
"Warning: Parsing callerid history file line %d: %s.\n",
callerid_lloc.first_line, message);
}

84
src/client.c Normal file
View File

@ -0,0 +1,84 @@
/*
* client functionality:
* * let a process issue commands (e.g. dial)
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* regular GNU system includes */
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
/* own header files */
#include "globals.h"
#include "client.h"
#include "server.h"
#include "util.h"
/*
* (try to) connect to server and issue call command
*
* returns 0 on success, -1 otherwise
*/
int client_make_call(char *number) {
int sock;
struct sockaddr_un local_name;
size_t size;
char *filename;
int bytes;
char *msg;
sock = socket(PF_LOCAL, SOCK_STREAM, 0);
if (sock < 0) {
perror("client: local socket()");
return -1;
}
filename = server_local_socket_name();
local_name.sun_family = AF_LOCAL;
strncpy(local_name.sun_path, filename, sizeof(local_name.sun_path));
size = SUN_LEN(&local_name);
if (connect(sock, (struct sockaddr *) &local_name, sizeof(local_name)) < 0) {
perror("client: local connect()");
return -1;
}
if (asprintf(&msg, "%c%s", LOCAL_MSG_CALL, number) < 0) {
fprintf(stderr, "asprintf error");
return -1;
}
bytes = write(sock, msg, 1 + strlen(number) + 1);
if (bytes < 0) {
perror("socket write");
return -1;
}
free(msg);
close(sock);
free(filename);
return 0;
}

25
src/client.h Normal file
View File

@ -0,0 +1,25 @@
/*
* client functionality:
* * let a process issue commands (dial)
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
int client_make_call(char *number);

490
src/controlpad.c Normal file
View File

@ -0,0 +1,490 @@
/*
* The key pad
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* regular GNU system includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* GTK */
#include <gtk/gtk.h>
/* own header files */
#include "globals.h"
#include "session.h"
#include "isdn.h"
#include "util.h"
#include "callerid.h"
/* graphical symbols */
#include "backspace.xpm"
#include "redial.xpm"
#include "mute.xpm"
/*
* called on preset edit confirmation (OK button)
* -> sets new preset values (name, number) and destroys window
*
* input: widget = the OK button, set data:
* "entry_name" - the entry with the new preset name
* "entry_number" - the entry with the new preset number
* "button" - the preset button
* "number" - the preset button number
* "window" - the window to destroy after setting values
* data = the session
*/
static void controlpad_preset_edit_ok(GtkWidget *widget, gpointer *data) {
session_t *session = (session_t *) data;
GtkWidget *entry_name = gtk_object_get_data(GTK_OBJECT(widget),
"entry_name");
GtkWidget *entry_number = gtk_object_get_data(GTK_OBJECT(widget),
"entry_number");
GtkWidget *button = gtk_object_get_data(GTK_OBJECT(widget), "button");
int n = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "number"));
free(session->preset_names[n]);
session->preset_names[n] = strdup(gtk_entry_get_text(GTK_ENTRY(entry_name)));
free(session->preset_numbers[n]);
session->preset_numbers[n] = strdup(
gtk_entry_get_text(GTK_ENTRY(entry_number)));
gtk_label_set_text(GTK_LABEL(GTK_BIN(button)->child),
gtk_entry_get_text(GTK_ENTRY(entry_name)));
gtk_widget_destroy(gtk_object_get_data(GTK_OBJECT(widget), "window"));
}
/*
* called on right-click on preset button to configure
*
* input: widget = the preset button
* event = the event (we determine the clicked mouse button from it)
* data = the session
*/
static gint controlpad_preset_edit_cb(GtkWidget *widget, GdkEventButton *event,
gpointer data) {
if (event->button == 3) {
session_t *session = (session_t *) data;
char *buttoncode = (char *)gtk_object_get_data(GTK_OBJECT(widget), "desc");
int n = strtol(&buttoncode[1], NULL, 0);
GtkWidget *window;
GtkWidget *button_box;
GtkWidget *button;
GtkWidget *label;
GtkWidget *table;
GtkWidget *entry_name;
GtkWidget *entry_number;
char *title;
char *labeltext;
window = gtk_dialog_new();
asprintf(&title, _("Preset %c"), buttoncode[1] + 1);
gtk_window_set_title(GTK_WINDOW(window), title);
gtk_window_set_modal(GTK_WINDOW(window), TRUE);
/* vbox area */
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(window)->vbox), 0);
asprintf(&labeltext,
_("Please input new preset data for button %c:"), buttoncode[1] + 1);
label = gtk_label_new(labeltext);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), label,
TRUE, FALSE, 0);
gtk_misc_set_padding(GTK_MISC(label), 10, 10);
gtk_widget_show(label);
table = gtk_table_new(2, 2, FALSE);
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), table,
TRUE, FALSE, 0);
gtk_widget_show(table);
label = gtk_label_new(_("Name:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
gtk_widget_show(label);
label = gtk_label_new(_("Number:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
gtk_widget_show(label);
entry_name = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(entry_name), session->preset_names[n]);
gtk_table_attach_defaults(GTK_TABLE(table), entry_name, 1, 2, 0, 1);
gtk_widget_show(entry_name);
entry_number = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(entry_number), session->preset_numbers[n]);
gtk_table_attach_defaults(GTK_TABLE(table), entry_number, 1, 2, 1, 2);
gtk_widget_show(entry_number);
/* action area */
button_box = gtk_hbutton_box_new();
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->action_area),
button_box);
gtk_widget_show(button_box);
/* OK button */
button = gtk_button_new_with_label(_("OK"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_object_set_data(GTK_OBJECT(button), "entry_name", entry_name);
gtk_object_set_data(GTK_OBJECT(button), "entry_number", entry_number);
gtk_object_set_data(GTK_OBJECT(button), "button", widget);
gtk_object_set_data(GTK_OBJECT(button), "number", GINT_TO_POINTER(n));
gtk_object_set_data(GTK_OBJECT(button), "window", window);
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(controlpad_preset_edit_ok),
session);
gtk_widget_show(button);
/* cancel button */
button = gtk_button_new_with_label(_("Cancel"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT(window));
gtk_widget_show(button);
gtk_widget_show(window);
free(labeltext);
free(title);
return TRUE; /* event handled */
} else {
return FALSE;
}
}
/*
* called when button in key pad clicked (except mute)
*/
static void controlpad_button_cb(GtkWidget *button, gpointer data) {
session_t *session = (session_t *) data;
char *c = (char *) gtk_object_get_data(GTK_OBJECT(button), "desc");
char *temp;
switch (session->state) {
case STATE_READY: /* manipulate dial box */
if ((*c >= '0' && *c <= '9') || *c == '*' || *c == '#') { /* new char */
gtk_entry_append_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
->entry), c);
} else if (*c == 'P') { /* preset button */
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)->entry),
session->preset_numbers[strtol(&c[1], NULL, 0)]);
} else if (*c == 'B') { /* clear one byte (Backspace) */
temp = strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(
session->dial_number_box)->entry)));
if (strlen(temp) > 0) {
temp[strlen(temp) - 1] = 0;
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
->entry), temp);
}
free(temp);
} else if (*c == 'C') { /* clear entry */
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
->entry), "");
} else if (*c == 'R') { /* Redial from history */
do {
temp = g_list_nth_data(session->dial_number_history,
session->dial_number_history_pointer);
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
->entry), temp);
if (session->dial_number_history_pointer <
session->dial_number_history_maxlen)
session->dial_number_history_pointer++;
if (session->dial_number_history_pointer ==
session->dial_number_history_maxlen)
session->dial_number_history_pointer = 0;
} while (*temp == '\0' && session->dial_number_history_pointer != 0);
}
gtk_widget_grab_focus(GTK_WIDGET(GTK_COMBO(session->dial_number_box)
->entry));
gtk_entry_set_position(GTK_ENTRY(GTK_COMBO(session->dial_number_box)
->entry), -1);
break;
case STATE_CONVERSATION: /* touchtones */
if ((*c >= '0' && *c <= '9') || *c == '*' || *c == '#') { /* new tt */
#define TOUCHTONE_LENGTH 0.1
session->touchtone_countdown_isdn = TOUCHTONE_LENGTH * ISDN_SPEED;
session->touchtone_countdown_audio =
TOUCHTONE_LENGTH * session->audio_speed_out;
session->touchtone_index =
*c == '*' ? 9 : *c == '0' ? 10 : *c == '#' ? 11 : *c - '1';
}
break;
default: /* other states */
;
}
}
/*
* called when mute button in key pad toggled
*/
static void controlpad_mute_cb(GtkWidget *button, gpointer data) {
session_t *session = (session_t *) data;
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { /* muted */
session->option_muted = 1;
gtk_widget_show(session->muted_warning);
} else { /* unmuted */
session->option_muted = 0;
gtk_widget_hide(session->muted_warning);
}
}
/*
* called when record / local / remote checkbutton has been toggled
*/
static void controlpad_record_cb(GtkWidget *button, gpointer data) {
session_t *session = (session_t *) data;
char *digits = NULL;
if (button == session->record_checkbutton) {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { /* record! */
session->option_record = 1;
if (session->state == STATE_CONVERSATION) {
if (recording_open(session->recorder,
digits = util_digitstime(&session->vcon_time),
session->option_recording_format))
{
fprintf(stderr, "Error opening audio file.\n");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
session->record_checkbutton), FALSE);
return;
}
free(digits);
cid_row_mark_record(session, session->cid_num - 1);
}
} else { /* don't record! */
session->option_record = 0;
if (session->state == STATE_CONVERSATION) {
recording_write(session->recorder, session->rec_buf_local,
session->rec_buf_local_index, RECORDING_LOCAL);
recording_write(session->recorder, session->rec_buf_remote,
session->rec_buf_remote_index, RECORDING_REMOTE);
recording_close(session->recorder);
session->rec_buf_local_index = 0;
session->rec_buf_remote_index = 0;
}
}
gtk_widget_set_sensitive(session->record_checkbutton_local,
session->option_record);
gtk_widget_set_sensitive(session->record_checkbutton_remote,
session->option_record);
} else if (button == session->record_checkbutton_local) {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
/* record local channel (if recording is selected at all)! */
session->option_record_local = 1;
} else { /* don't record local channel! */
session->option_record_local = 0;
}
} else { /* button == session->record_checkbutton_remote */
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
/* record remote channel (if recording is selected at all)! */
session->option_record_remote = 1;
} else { /* don't record remote channel! */
session->option_record_remote = 0;
}
}
}
/*
* The key pad etc.
*/
GtkWidget *controlpad_new(session_t *session) {
char *labels[4][5] = {{"1", "2", "3", "B", session->preset_names[0]},
{"4", "5", "6", "C", session->preset_names[1]},
{"7", "8", "9", "R", session->preset_names[2]},
{"*", "0", "#", "M", session->preset_names[3]}};
char *tips[4][5] = {
{",-./", "abc", "def", N_("Backspace"), N_("Preset 1")},
{"ghi", "jkl", "mno", N_("Clear Number"), N_("Preset 2")},
{"pqrs", "tuv", "wxyz", N_("Redial"), N_("Preset 3")},
{"", "0...9", "", N_("Mute Microphone"), N_("Preset 4")}};
char *presetcodes[4] = {"P0", "P1", "P2", "P3"};
GtkWidget *frame;
GtkWidget *hbox;
GtkWidget *table;
GtkWidget *button;
GtkWidget *recordframe;
GtkWidget *recordbox;
GtkWidget *record_checkbutton;
GtkWidget *record_checkbutton_local;
GtkWidget *record_checkbutton_remote;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
GtkWidget *pixmapwid;
GtkTooltips *tooltips;
int i, j;
tooltips = gtk_tooltips_new();
/* tooltips are often grey by default and have to be set up with a gtkrc
file:
style "gtk-tooltips-style" {
bg[NORMAL] = "#ffffc0"
}
widget "gtk-tooltips" style "gtk-tooltips-style"
*/
frame = gtk_frame_new(_("Control"));
gtk_container_set_border_width(GTK_CONTAINER(frame), 8);
hbox = gtk_hbox_new(FALSE, 15);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
gtk_container_add(GTK_CONTAINER(frame), hbox);
gtk_widget_show(hbox);
table = gtk_table_new(4, 3, FALSE);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, FALSE, 5);
gtk_widget_show(table);
for (i = 0; i < 5; i++) { /* columns */
for (j = 0; j < 4; j++) { /* rows */
if (i == 3 && j == 3) { /* mute */
button = gtk_toggle_button_new();
style = gtk_widget_get_style(session->main_window);
pixmap = gdk_pixmap_create_from_xpm_d(session->main_window->window,
&mask,
&style->bg[GTK_STATE_NORMAL],
(gchar **) mute_xpm);
pixmapwid = gtk_pixmap_new(pixmap, mask);
gtk_container_add(GTK_CONTAINER(button), pixmapwid);
gtk_widget_show(pixmapwid);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
session->option_muted);
session->mute_button = button;
gtk_signal_connect(GTK_OBJECT(button), "toggled",
GTK_SIGNAL_FUNC(controlpad_mute_cb), session);
} else { /* everything else (except mute) */
if (i == 3 && j == 0) { /* backspace icon */
button = gtk_button_new();
style = gtk_widget_get_style(session->main_window);
pixmap = gdk_pixmap_create_from_xpm_d(session->main_window->window,
&mask,
&style->bg[GTK_STATE_NORMAL],
(gchar **) backspace_xpm);
pixmapwid = gtk_pixmap_new(pixmap, mask);
gtk_container_add(GTK_CONTAINER(button), pixmapwid);
gtk_widget_show(pixmapwid);
} else if (i == 3 && j == 2) { /* redial icon */
button = gtk_button_new();
style = gtk_widget_get_style(session->main_window);
pixmap = gdk_pixmap_create_from_xpm_d(session->main_window->window,
&mask,
&style->bg[GTK_STATE_NORMAL],
(gchar **) redial_xpm);
pixmapwid = gtk_pixmap_new(pixmap, mask);
gtk_container_add(GTK_CONTAINER(button), pixmapwid);
gtk_widget_show(pixmapwid);
} else { /* icon with letter (or description) */
button = gtk_button_new_with_label(labels[j][i]);
gtk_signal_connect(GTK_OBJECT(button), "button-press-event",
GTK_SIGNAL_FUNC(controlpad_preset_edit_cb),
session);
}
/* connect callback to widget */
gtk_object_set_data(GTK_OBJECT(button), "desc",
i < 4 ? labels[j][i] : presetcodes[j]);
gtk_signal_connect(GTK_OBJECT(button), "pressed",
GTK_SIGNAL_FUNC(controlpad_button_cb), session);
}
if (*tips[j][i])
gtk_tooltips_set_tip(tooltips, button, _(tips[j][i]), NULL);
gtk_table_attach_defaults(GTK_TABLE(table), button, i, i + 1, j, j + 1);
gtk_widget_set_size_request(button, i < 3 ? 30 : i == 3 ? 20 : 100, -1);
gtk_widget_show(button);
}
gtk_table_set_col_spacing(GTK_TABLE(table), i, i < 2 ? 5 : 15);
}
recordframe = gtk_frame_new(_("Recording"));
gtk_box_pack_start(GTK_BOX(hbox), recordframe, TRUE, FALSE, 5);
gtk_widget_show(recordframe);
recordbox = gtk_table_new(2, 3, FALSE);
gtk_table_set_row_spacings(GTK_TABLE(recordbox), 0);
gtk_table_set_col_spacings(GTK_TABLE(recordbox), 20);
gtk_container_add(GTK_CONTAINER(recordframe), recordbox);
gtk_widget_show(recordbox);
record_checkbutton =
gtk_check_button_new_with_label(_("Record to file"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_checkbutton),
session->option_record);
gtk_table_attach(GTK_TABLE(recordbox), record_checkbutton,
0, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
gtk_widget_show(record_checkbutton);
gtk_signal_connect(GTK_OBJECT(record_checkbutton), "toggled",
GTK_SIGNAL_FUNC(controlpad_record_cb), session);
session->record_checkbutton = record_checkbutton;
record_checkbutton_local =
gtk_check_button_new_with_label(_("Record local channel"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_checkbutton_local),
session->option_record_local);
gtk_table_attach(GTK_TABLE(recordbox), record_checkbutton_local,
1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
gtk_widget_show(record_checkbutton_local);
gtk_signal_connect(GTK_OBJECT(record_checkbutton_local), "toggled",
GTK_SIGNAL_FUNC(controlpad_record_cb), session);
session->record_checkbutton_local = record_checkbutton_local;
record_checkbutton_remote =
gtk_check_button_new_with_label(_("Record remote channel"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_checkbutton_remote),
session->option_record_remote);
gtk_table_attach(GTK_TABLE(recordbox), record_checkbutton_remote,
1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
gtk_widget_show(record_checkbutton_remote);
gtk_signal_connect(GTK_OBJECT(record_checkbutton_remote), "toggled",
GTK_SIGNAL_FUNC(controlpad_record_cb), session);
session->record_checkbutton_remote = record_checkbutton_remote;
if (!session->option_record) {
gtk_widget_set_sensitive(record_checkbutton_local, FALSE);
gtk_widget_set_sensitive(record_checkbutton_remote, FALSE);
}
return frame;
}
/* called when control pad state check button is toggled */
void controlpad_toggle_cb(GtkWidget *widget _U_,
gpointer data, guint action _U_) {
session_t *session = (session_t *) data;
if (GTK_CHECK_MENU_ITEM (session->controlpad_check_menu_item)->active) {
gtk_widget_show(session->controlpad);
session->option_show_controlpad = 1;
} else {
gtk_widget_hide(session->controlpad);
session->option_show_controlpad = 0;
/* shrink if no growing callerid monitor present */
if (!session->option_show_callerid)
gtk_window_resize(GTK_WINDOW(session->main_window), 1, 1);
}
}

29
src/controlpad.h Normal file
View File

@ -0,0 +1,29 @@
/*
* The key pad
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* GTK */
#include <gtk/gtk.h>
GtkWidget *controlpad_new(session_t *session);
void controlpad_toggle_cb(GtkWidget *widget _U_,
gpointer data, guint action _U_);

145
src/fxgenerator.c Normal file
View File

@ -0,0 +1,145 @@
/*
* The sound effects generator
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* regular GNU system includes */
#include <stdio.h>
#include <math.h>
/* own header files */
#include "globals.h"
#include "session.h"
/* all time constants in seconds or Hz */
#define RING_PERIOD 4
#define RING_LENGTH 1.3
#define RING_FREQUENCY 1300
/* fade in/out reciprocal period: */
#define RING_FADE_LENGTH 0.003
#define RING_SHORT_PERIOD 0.044
#define RING_SHORT_LENGTH (RING_SHORT_PERIOD / 2)
#define RINGING_FREQUENCY 425
/*
* Effect generator
* input: session: session, used element: audio_LUT_generate
* effect: the effect
* index: parameter for effect (e.g. which touchtone)
* EFFECT_TOUCHTONE: row * 3 + column (each 0-based)
* seconds: position of sample in seconds
* returns: generated ulaw sample
*/
unsigned char fxgenerate(session_t *session, enum effect_t effect,
int index, double seconds) {
unsigned char x; /* generated ulaw sample (return value) */
double rest; /* monitor the period in seconds modulo 4 */
double rest2; /* monitor (short) sinus period */
double factor; /* envelope factor */
double factor2; /* envelope help factor (short periods) */
double f1, f2; /* frequencies for touchtones (row, column) */
switch(effect) {
case EFFECT_RING: /* somebody's calling */
case EFFECT_TEST: /* play test sound */
if (effect == EFFECT_RING) {
rest = fmod(seconds, RING_PERIOD); /* 4 sec period */
} else {
rest = seconds; /* infinite period */
}
rest2 = fmod(seconds, RING_SHORT_PERIOD); /* short period */
if (rest < RING_FADE_LENGTH) { /* fade in */
factor = -cos(rest * M_PI / RING_FADE_LENGTH) / 2 + 0.5;
} else if (rest > RING_LENGTH - RING_FADE_LENGTH &&
rest < RING_LENGTH) { /* fade out */
factor = -cos((RING_LENGTH - rest) * 2 * M_PI / (RING_FADE_LENGTH * 2))
/ 2 + 0.5;
} else if (rest >= RING_LENGTH) { /* pause */
factor = 0;
} else { /* (potential) beep */
factor = 1;
}
if (rest2 > RING_SHORT_PERIOD - 0.5 * RING_FADE_LENGTH) {
/* fade in short period (1/2) */
factor2 = -sin((RING_SHORT_PERIOD - rest2)
* 2 * M_PI / (RING_FADE_LENGTH * 2)) / 2 + 0.5;
} else if (rest2 < 0.5 * RING_FADE_LENGTH) {
/* fade in short period (2/2) */
factor2 = sin(rest2 * 2 * M_PI / (RING_FADE_LENGTH * 2)) / 2 + 0.5;
} else if (rest2 > RING_SHORT_LENGTH - 0.5 * RING_FADE_LENGTH &&
rest2 < RING_SHORT_LENGTH + 0.5 * RING_FADE_LENGTH) {
/* fade out short period */
factor2 = -sin((rest2 - RING_SHORT_LENGTH)
* 2 * M_PI / (RING_FADE_LENGTH * 2)) / 2 + 0.5;
} else if (rest2 <= RING_SHORT_LENGTH) { /* just beep */
factor2 = 1;
} else {
factor2 = 0; /* short pause */
}
factor = factor * factor2;
x = session->audio_LUT_generate[
(int)(sin(seconds * 2 * M_PI * RING_FREQUENCY)
* factor * 127.5 + 127.5)];
break;
case EFFECT_RINGING: /* waiting for the other end to pick up the phone */
rest = fmod(seconds, 5);
if (rest >= 2 && rest < 3) {
x = session->audio_LUT_generate[ /* beep */
(int)(sin(seconds * 2 * M_PI * RINGING_FREQUENCY) * 127.5 + 127.5)];
} else {
x = session->audio_LUT_generate[128]; /* pause */
}
break;
case EFFECT_TOUCHTONE: /* clicked key pad in conversation mode */
switch (index / 3) { /* row frequency */
case 0: f1 = 697; break;
case 1: f1 = 770; break;
case 2: f1 = 852; break;
case 3: f1 = 941; break;
default: f1 = 0;
}
switch (index % 3) { /* column frequency */
case 0: f2 = 1209; break;
case 1: f2 = 1336; break;
case 2: f2 = 1477; break;
case 3: f2 = 1633; break;
default: f2 = 0;
}
x = session->audio_LUT_generate[
(int)((sin(seconds * 2 * M_PI * f1) + sin(seconds * 2 * M_PI * f2))
/ 2 * 127.5 * 0.7 + 127.5)];
break;
default:
fprintf(stderr, "fxgenerate: Unknown effect.\n");
x = 0;
}
return x;
}

28
src/fxgenerator.h Normal file
View File

@ -0,0 +1,28 @@
/*
* The sound effects generator
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* own header files */
#include "session.h"
unsigned char fxgenerate(session_t *session, enum effect_t, int index,
double seconds);

281
src/g711.c Normal file
View File

@ -0,0 +1,281 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#include "config.h"
/*
* g711.c
*
* u-law, A-law and linear PCM conversions.
*/
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
#define QUANT_MASK (0xf) /* Quantization field mask. */
#define NSEGS (8) /* Number of A-law segments. */
#define SEG_SHIFT (4) /* Left shift for segment number. */
#define SEG_MASK (0x70) /* Segment field mask. */
/* copy from CCITT G.711 specifications */
unsigned char _u2a[128] = { /* u- to A-law conversions */
1, 1, 2, 2, 3, 3, 4, 4,
5, 5, 6, 6, 7, 7, 8, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 27, 29, 31, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44,
46, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, 62,
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 91, 92, 93, 94, 95, 96,
97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 110, 111, 112,
113, 114, 115, 116, 117, 118, 119, 120,
121, 122, 123, 124, 125, 126, 127, 128};
unsigned char _a2u[128] = { /* A- to u-law conversions */
1, 3, 5, 7, 9, 11, 13, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 32, 33, 33, 34, 34, 35, 35,
36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 48, 49, 49,
50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 62, 63, 64, 64,
65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 79,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127};
/* see libst.h */
/*#ifdef SUPERCEDED*/
static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
static int
search(int val, short *table, int size)
{
int i;
for (i = 0; i < size; i++) {
if (val <= *table++)
return (i);
}
return (size);
}
/*
* linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
*
* linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
*
* Linear Input Code Compressed Code
* ------------------------ ---------------
* 0000000wxyza 000wxyz
* 0000001wxyza 001wxyz
* 000001wxyzab 010wxyz
* 00001wxyzabc 011wxyz
* 0001wxyzabcd 100wxyz
* 001wxyzabcde 101wxyz
* 01wxyzabcdef 110wxyz
* 1wxyzabcdefg 111wxyz
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
unsigned char
linear2alaw(int pcm_val) /* 2's complement (16-bit range) */
{
int mask;
int seg;
unsigned char aval;
if (pcm_val >= 0) {
mask = 0xD5; /* sign (7th) bit = 1 */
} else {
mask = 0x55; /* sign bit = 0 */
pcm_val = -pcm_val - 8;
}
/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_end, 8);
/* Combine the sign, segment, and quantization bits. */
if (seg >= 8) /* out of range, return maximum value. */
return (0x7F ^ mask);
else {
aval = seg << SEG_SHIFT;
if (seg < 2)
aval |= (pcm_val >> 4) & QUANT_MASK;
else
aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
return (aval ^ mask);
}
}
/*
* alaw2linear() - Convert an A-law value to 16-bit linear PCM
*
*/
int
alaw2linear(unsigned char a_val)
{
int t;
int seg;
a_val ^= 0x55;
t = (a_val & QUANT_MASK) << 4;
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
switch (seg) {
case 0:
t += 8;
break;
case 1:
t += 0x108;
break;
default:
t += 0x108;
t <<= seg - 1;
}
return ((a_val & SIGN_BIT) ? t : -t);
}
#define BIAS (0x84) /* Bias for linear code. */
/*
* linear2ulaw() - Convert a linear PCM value to u-law
*
* In order to simplify the encoding process, the original linear magnitude
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
* (33 - 8191). The result can be seen in the following encoding table:
*
* Biased Linear Input Code Compressed Code
* ------------------------ ---------------
* 00000001wxyza 000wxyz
* 0000001wxyzab 001wxyz
* 000001wxyzabc 010wxyz
* 00001wxyzabcd 011wxyz
* 0001wxyzabcde 100wxyz
* 001wxyzabcdef 101wxyz
* 01wxyzabcdefg 110wxyz
* 1wxyzabcdefgh 111wxyz
*
* Each biased linear code has a leading 1 which identifies the segment
* number. The value of the segment number is equal to 7 minus the number
* of leading 0's. The quantization interval is directly available as the
* four bits wxyz. * The trailing bits (a - h) are ignored.
*
* Ordinarily the complement of the resulting code word is used for
* transmission, and so the code word is complemented before it is returned.
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
unsigned char
linear2ulaw(int pcm_val) /* 2's complement (16-bit range) */
{
int mask;
int seg;
unsigned char uval;
/* Get the sign and the magnitude of the value. */
if (pcm_val < 0) {
pcm_val = BIAS - pcm_val;
mask = 0x7F;
} else {
pcm_val += BIAS;
mask = 0xFF;
}
/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_end, 8);
/*
* Combine the sign, segment, quantization bits;
* and complement the code word.
*/
if (seg >= 8) /* out of range, return maximum value. */
return (0x7F ^ mask);
else {
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
return (uval ^ mask);
}
}
/*
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM
*
* First, a biased linear code is derived from the code word. An unbiased
* output can then be obtained by subtracting 33 from the biased code.
*
* Note that this function expects to be passed the complement of the
* original code word. This is in keeping with ISDN conventions.
*/
int
ulaw2linear(unsigned char u_val)
{
int t;
/* Complement to obtain normal u-law value. */
u_val = ~u_val;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = ((u_val & QUANT_MASK) << 3) + BIAS;
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}
/*#endif*/
/* A-law to u-law conversion */
unsigned char
alaw2ulaw(unsigned char aval)
{
aval &= 0xff;
return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
(0x7F ^ _a2u[aval ^ 0x55]));
}
/* u-law to A-law conversion */
unsigned char
ulaw2alaw(unsigned char uval)
{
uval &= 0xff;
return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
(0x55 ^ (_u2a[0x7F ^ uval] - 1)));
}

32
src/g711.h Normal file
View File

@ -0,0 +1,32 @@
/*
* G.711 conversion function header file
* (adjusted for g711.c from SoX)
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
unsigned char linear2alaw(int pcm_val); /* 2's complement (16-bit range) */
int alaw2linear(unsigned char a_val);
unsigned char linear2ulaw(int pcm_val); /* 2's complement (16-bit range) */
int ulaw2linear(unsigned char u_val);
unsigned char alaw2ulaw(unsigned char aval);
unsigned char ulaw2alaw(unsigned char uval);

37
src/globals.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Global definitions to be included in ALL source files
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _ANT_GLOBALS_H
#define _ANT_GLOBALS_H
#include "config.h"
/* GNU gettext introduction */
#include <locale.h>
#include "gettext.h"
#define _(String) gettext (String)
#define N_(String) gettext_noop (String)
extern int debug;
#endif /* globals.h */

842
src/gtk.c Normal file
View File

@ -0,0 +1,842 @@
/*
* gtk GUI functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
/* regular GNU system includes */
#include <stdio.h>
#include <signal.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <string.h>
#include <time.h>
/* GTK */
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
/* own header files */
#include "globals.h"
#include "gtk.h"
#include "session.h"
#include "isdn.h"
#include "util.h"
#include "sound.h"
#include "callerid.h"
#include "llcheck.h"
#include "settings.h"
#include "gtksettings.h"
#include "controlpad.h"
/* graphical symbols */
#include "hangup.xpm"
#include "pickup.xpm"
#include "aboutlogo.xpm"
/*
#include "icon16x16.xpm"
#include "icon32x32.xpm"
*/
#include "icon48x48.xpm"
/*
#include "icon64x64.xpm"
*/
/* call timeout_callback each <this number> of milliseconds */
#define TIMER_DELAY 300
volatile int interrupted = 0; /* the caught signal will be stored here */
/*
* the quit (e.g. menu entry) callback
* prototype is this way to standardize to GtkItemFactoryCallback2
*
* this function will always be called when gtk is to finish
*
* input: data: session
*/
static void quit(GtkWidget *widget _U_, gpointer data, guint action _U_) {
session_t *session = (session_t *) data;
settings_history_write(session); /* write history */
settings_callerid_write(session); /* write callerid history */
gtk_handle_hang_up_button(NULL, data); /* simulate hang_up_button */
/* some (GUI) de-initialization, not directly session related */
llcheck_bar_deinit(session->llcheck_in);
llcheck_bar_deinit(session->llcheck_out);
gtk_main_quit();
}
/*
* main window delete_event callback
*
* input: data: session
*/
gint delete_event(GtkWidget *widget,
GdkEvent *event _U_,
gpointer data)
{
quit(widget, data, 0);
return FALSE; /* continue event handling */
}
/* handler for SIGTERM and SIGINT */
void terminate_signal_callback(int sig) {
interrupted = sig;
}
/*
* periodically (e.g. each 300 milliseconds) from gtk main loop called function
*/
gint timeout_callback(gpointer data) {
session_t *session = (session_t *) data;
if (interrupted) {
switch(interrupted) {
case SIGINT:
if (debug)
fprintf(stderr, "Ctrl-C caught.\n");
break;
case SIGTERM:
if (debug)
fprintf(stderr, "SIGTERM caught.\n");
break;
default:
fprintf(stderr, "Warning: Unknown signal caught.\n");
}
quit(NULL, data, 0);
}
if (session->state == STATE_CONVERSATION) {
char *timediff = timediff_str(time(NULL), session->vcon_time);
char *buf;
if (0 > asprintf(&buf, "%s %s",
state_data[session->state].status_bar, timediff))
fprintf(stderr, "Warning: timeout_callback: asprintf error.\n");
gtk_statusbar_pop(GTK_STATUSBAR(session->status_bar),
session->phone_context_id);
gtk_statusbar_push(GTK_STATUSBAR(session->status_bar),
session->phone_context_id,
buf);
free(buf);
free(timediff);
}
if (session->state == STATE_PLAYBACK) {
char *timediff = timediff_str(time(NULL),
session->effect_playback_start_time);
char *buf;
if (0 > asprintf(&buf, "%s %s",
state_data[session->state].status_bar, timediff))
fprintf(stderr, "Warning: timeout_callback: asprintf error.\n");
gtk_statusbar_pop(GTK_STATUSBAR(session->status_bar),
session->phone_context_id);
gtk_statusbar_push(GTK_STATUSBAR(session->status_bar),
session->phone_context_id,
buf);
free(buf);
free(timediff);
}
return TRUE; /* call it again */
}
/*
* some GUI tools
*/
/*
* return a dialog window with a (big) label and an ok button to close
* (good for displaying a note)
*
* justification: justification of label (e.g. GTK_JUSTIFY_LEFT)
*
* NOTE: caller has to show the window itself with gtk_widget_show()
* and maybe want to make it modal with
* gtk_window_set_modal(GTK_WINDOW(window), TRUE);
*/
GtkWidget *ok_dialog_get(char *title, char *contents,
GtkJustification justification) {
GtkWidget *window;
GtkWidget *button_box;
GtkWidget *button;
GtkWidget *label;
window = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(window), title);
/* vbox area */
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(window)->vbox), 0);
label = gtk_label_new(contents);
gtk_label_set_justify(GTK_LABEL(label), justification);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), label,
TRUE, FALSE, 0);
gtk_misc_set_padding(GTK_MISC(label), 10, 10);
gtk_widget_show(label);
/* action area */
button_box = gtk_hbutton_box_new();
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->action_area),
button_box);
gtk_widget_show(button_box);
/* OK button */
button = gtk_button_new_with_label(_("OK"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT(window));
gtk_widget_show(button);
/* caller has to show the window itself */
return window;
}
/*
* shortcut to display a note about audio devices not available
*/
void show_audio_error_dialog(void) {
GtkWidget *dialog;
dialog = ok_dialog_get(_("ANT Note"),
_("Can't open audio device.\n"
"Please stop other applications using\n"
"the audio device(s) or check your\n"
"device settings and try again."),
GTK_JUSTIFY_CENTER);
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
gtk_widget_show(dialog);
}
/**********************
* some GUI callbacks *
**********************/
/*
* File Menu entries
*/
struct info_row_t {
gchar *tag;
gchar *value;
};
/* Info window */
static void cb_info_window(GtkWidget *widget _U_, gpointer data,
guint action _U_) {
session_t *session = (session_t *) data;
int inactive = session->option_release_devices &&
(session->state == STATE_READY || session->state == STATE_RINGING_QUIET);
struct info_row_t rows[] = {
{ N_("Sound input device:"), strdup(session->audio_device_name_in)},
{ N_("Input speed:"), inactive ? strdup(_("[inactive]")) :
ltostr(session->audio_speed_in) },
{ N_("Input sample size (bits):"), inactive ?
strdup(_("[inactive]")) : ltostr(session->audio_sample_size_in * 8)},
{ N_("Input fragment size (samples):"), inactive ? strdup(_("[inactive]")) :
ltostr(session->fragment_size_in / session->audio_sample_size_in)},
{ N_("Input channels:"), inactive ? strdup(_("[inactive]")) : ltostr(1) },
{ "", strdup("") },
{ N_("Sound output device:"), strdup(session->audio_device_name_out)},
{ N_("Output speed:"), inactive ? strdup(_("[inactive]")) :
ltostr(session->audio_speed_out) },
{ N_("Output sample size (bits):"), inactive ?
strdup(_("[inactive]")) : ltostr(session->audio_sample_size_out*8)},
{ N_("Input fragment size (samples):"), inactive ? strdup(_("[inactive]")) :
ltostr(session->fragment_size_out / session->audio_sample_size_out)},
{ N_("Output channels:"), inactive ? strdup(_("[inactive]")) : ltostr(1) },
{ "", strdup("") },
{ N_("ISDN device:"), strdup(session->isdn_device_name) },
{ N_("ISDN speed (samples):"), ltostr(8000) },
{ N_("ISDN sample size (bits):"), ltostr(8) },
{ N_("ISDN fragment size (bytes):"), ltostr(255) }
};
unsigned int i;
GtkWidget *window; /* the window itself, actually a GtkDialog */
GtkWidget *table; /* for tag->value pairs */
GtkWidget *label;
GtkWidget *button_box;
GtkWidget *button;
GtkWidget *separator;
window = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(window), _("ANT Info"));
/* the info area */
table = gtk_table_new(sizeof(rows) / sizeof(struct info_row_t), 2, FALSE);
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
gtk_table_set_col_spacings(GTK_TABLE(table), 10);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), table);
gtk_widget_show(table);
for (i = 0; i < sizeof(rows) / sizeof(struct info_row_t); i++) {
if (strcmp(rows[i].tag, "")) { /* normal data */
label = gtk_label_new(_(rows[i].tag));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, i, i + 1);
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_widget_show(label);
label = gtk_label_new(rows[i].value);
gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, i, i + 1);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_widget_show(label);
} else { /* separator */
separator = gtk_hseparator_new();
gtk_table_attach(GTK_TABLE(table), separator, 0, 2, i, i + 1,
GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 5);
gtk_widget_show(separator);
}
free(rows[i].value); /* free stdrup() mem */
}
/* action area */
button_box = gtk_hbutton_box_new();
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->action_area),
button_box);
gtk_widget_show(button_box);
button = gtk_button_new_with_label(_("OK"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT(window));
gtk_widget_show(button);
gtk_window_set_modal(GTK_WINDOW(window), TRUE);
/* show everything */
gtk_widget_show(window);
}
/*
* Options menu entries
*/
/*
* Help menu entries
*/
/* the about menu entry callback */
static void cb_about(GtkWidget *widget _U_, gpointer data _U_, guint action _U_) {
GtkWidget *window;
GtkWidget *button_box;
GtkWidget *button;
GtkWidget *label;
GdkPixmap* pixmap;
GdkBitmap* mask;
GtkStyle* style;
GtkWidget* pixmapwidget;
char *message;
window = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(window), _("About ANT"));
/* vbox area */
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(window)->vbox), 0);
gtk_widget_realize(window);
style = gtk_widget_get_style(window);
pixmap = gdk_pixmap_create_from_xpm_d(window->window,
&mask,
NULL,
(gchar**) aboutlogo_xpm);
pixmapwidget = gtk_pixmap_new(pixmap, mask);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox),
pixmapwidget, TRUE, TRUE, 0);
gtk_widget_show(pixmapwidget);
asprintf(&message, _("ANT (ANT is Not a Telephone) Version %s\n"
"Copyright 2002, 2003 Roland Stigge\n\n"
"This is an ISDN telephone application\n"
"written for GNU/Linux and ISDN4Linux for\n"
"communicating via a full duplex soundcard (or\n"
"multiple sound devices if you like) and an\n"
"audio capable ISDN4Linux ISDN device\n\n"
"Contact:\n"
"Roland Stigge, stigge@antcom.de\n"
"http://www.antcom.de/\n"
"Mailing list: ant-phone-devel@nongnu.org"), VERSION);
label = gtk_label_new(message);
free(message);
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), label,
TRUE, FALSE, 0);
gtk_misc_set_padding(GTK_MISC(label), 10, 10);
gtk_widget_show(label);
/* action area */
button_box = gtk_hbutton_box_new();
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->action_area),
button_box);
gtk_widget_show(button_box);
/* OK button */
button = gtk_button_new_with_label(_("OK"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT(window));
gtk_widget_show(button);
gtk_widget_show(window);
}
/* the about menu entry callback */
static void cb_license(GtkWidget *widget _U_, gpointer data _U_, guint action _U_) {
GtkWidget *window = ok_dialog_get(_("ANT License"),
_("ANT (ANT is Not a Telephone)\n"
"Copyright (C) 2002, 2003 Roland Stigge\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, "
"USA."), GTK_JUSTIFY_CENTER);
gtk_widget_show(window);
}
/*
* get the main menu widget
*
* input: window: parent window to integrate accelerators
* returns: the widget yet to pack
*
* NOTE: assumes other parts to be initialized (maybe not shown already)
*/
GtkWidget *get_main_menu(GtkWidget *window, session_t *session) {
/* The main menu structure */
GtkItemFactoryEntry main_menu_items[] = {
/*path accel. callb. cb par. kind extra */
{_("/Phon_e"), NULL, NULL, 0, "<Branch>", NULL},
{_("/Phone/_Info Window"),NULL, cb_info_window,0, NULL, NULL},
{_("/Phone/_Line Level Check"),
NULL, llcheck, 0, NULL, NULL},
{_("/Phone/"), NULL, NULL, 0, "<Separator>", NULL},
{_("/Phone/_Quit"), "<alt>X", quit, 0, NULL, NULL},
{_("/_View"), NULL, NULL, 0, "<Branch>", NULL},
{_("/View/_Caller ID Monitor"),
NULL, cid_toggle_cb, 0, "<CheckItem>", NULL},
{_("/View/_Line Level Meters"),
NULL, llcheck_toggle_cb,0, "<CheckItem>", NULL},
{_("/View/Control _Pad"), NULL, controlpad_toggle_cb,0,"<CheckItem>", NULL},
{_("/_Options"), NULL, NULL, 0, "<Branch>", NULL},
{_("/Options/_Settings"), NULL, gtksettings_cb,0, NULL, NULL},
{_("/_Help"), NULL, NULL, 0, "<LastBranch>",NULL},
{_("/Help/_About"), NULL, cb_about, 0, NULL, NULL},
{_("/Help/_License"), NULL, cb_license, 0, NULL, NULL}
/* set to session by ..._create_items_ac -^ */
};
GtkItemFactory *item_factory;
GtkAccelGroup *accel_group;
char* temp;
gint nmenu_items = sizeof(main_menu_items) / sizeof(main_menu_items[0]);
accel_group = gtk_accel_group_new();
item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>",
accel_group);
gtk_item_factory_create_items_ac(item_factory, nmenu_items, main_menu_items,
session, 2);
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
/* save connection to menu item(s), set defaults */
session->cid_check_menu_item = gtk_item_factory_get_item(item_factory,
temp = stripchr(_("/View/_Caller ID Monitor"), '_'));
free(temp);
session->llcheck_check_menu_item = gtk_item_factory_get_item(item_factory,
temp = stripchr(_("/View/_Line Level Meters"), '_'));
free(temp);
session->controlpad_check_menu_item = gtk_item_factory_get_item(item_factory,
temp = stripchr(_("/View/Control _Pad"), '_'));
free(temp);
session->menuitem_settings = gtk_item_factory_get_item(item_factory,
temp = stripchr(_("/Options/_Settings"), '_'));
free(temp);
session->menuitem_line_check = gtk_item_factory_get_item(item_factory,
temp = stripchr(_("/Phone/_Line Level Check"), '_'));
free(temp);
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(session->cid_check_menu_item),
session->option_show_callerid);
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(session->llcheck_check_menu_item),
session->option_show_llcheck);
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(session->controlpad_check_menu_item),
session->option_show_controlpad);
return gtk_item_factory_get_widget(item_factory, "<main>");
}
/*
* called on key pressed in combo box entry
*/
static gint entry_key_cb(GtkWidget *entry, GdkEventKey *event, gpointer data) {
session_t *session = (session_t *) data;
if (event->keyval == GDK_KP_Enter) { /* catch keyboard keypad Enter */
gtk_button_clicked(GTK_BUTTON(session->pick_up_button));
/* the keyboard keypad Enter generates an unneeded character, so
discard it: */
gtk_signal_emit_stop_by_name(GTK_OBJECT(entry), "key-press-event");
return TRUE; /* event handled */
} else {
return FALSE;
}
}
/*
* Get the basic dial box with entry and dial / hang up buttons
* sets dial box members in session
* NOTE: caller has to gtk_widget_show it itself
*/
GtkWidget *get_dial_box(session_t *session) {
GtkWidget *frame;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *label_hbox;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
GtkWidget *pixmapwid;
frame = gtk_frame_new(_("Dialing"));
gtk_container_set_border_width(GTK_CONTAINER(frame), 8);
/* dial hbox */
hbox = gtk_hbox_new(FALSE, 10);
gtk_container_add(GTK_CONTAINER(frame), hbox);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 8);
gtk_widget_show(hbox);
/* dial label */
label = gtk_label_new(_("Number:"));
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
gtk_widget_show(label);
/* dial number combo box */
session->dial_number_box = gtk_combo_new();
gtk_combo_set_popdown_strings(GTK_COMBO(session->dial_number_box),
session->dial_number_history);
gtk_combo_set_use_arrows_always(GTK_COMBO(session->dial_number_box), TRUE);
gtk_widget_set_size_request(session->dial_number_box, 180, -1);
gtk_box_pack_start(GTK_BOX(hbox), session->dial_number_box,
TRUE, TRUE, 0);
gtk_widget_show(session->dial_number_box);
gtk_signal_disconnect(GTK_OBJECT(GTK_COMBO(session->dial_number_box)->entry),
GTK_COMBO(session->dial_number_box)->activate_id);
/* pick up button */
session->pick_up_button = gtk_button_new();
gtk_box_pack_start(GTK_BOX(hbox), session->pick_up_button, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(session->pick_up_button), "clicked",
GTK_SIGNAL_FUNC(gtk_handle_pick_up_button),
(gpointer) session);
gtk_widget_show(session->pick_up_button);
/* activate dial button when pressing enter in entry widget */
gtk_signal_connect_object(GTK_OBJECT(GTK_COMBO(session->dial_number_box)
->entry),
"activate",
GTK_SIGNAL_FUNC(gtk_button_clicked),
GTK_OBJECT(session->pick_up_button));
/* handle special keys */
gtk_signal_connect(GTK_OBJECT(GTK_COMBO(session->dial_number_box)->entry),
"key-press-event", GTK_SIGNAL_FUNC(entry_key_cb), session);
/* pick up button hbox */
label_hbox = gtk_hbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(session->pick_up_button), label_hbox);
gtk_widget_show(label_hbox);
/* pick up button symbol */
style = gtk_widget_get_style(session->main_window);
pixmap = gdk_pixmap_create_from_xpm_d(session->main_window->window,
&mask,
&style->bg[GTK_STATE_NORMAL],
(gchar **) pickup_xpm);
pixmapwid = gtk_pixmap_new(pixmap, mask);
gtk_box_pack_start(GTK_BOX(label_hbox), pixmapwid, FALSE, FALSE, 2);
gtk_widget_show(pixmapwid);
/* pick up button label */
session->pick_up_label = gtk_label_new(NULL);
gtk_box_pack_start(GTK_BOX(label_hbox), session->pick_up_label,
TRUE, FALSE, 16); /* expand but fill up outside label */
gtk_widget_show(session->pick_up_label);
/* hang up button */
session->hang_up_button = gtk_button_new();
gtk_box_pack_start(GTK_BOX(hbox), session->hang_up_button, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(session->hang_up_button), "clicked",
GTK_SIGNAL_FUNC(gtk_handle_hang_up_button),
(gpointer) session);
gtk_widget_show(session->hang_up_button);
/* pick up button hbox */
label_hbox = gtk_hbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(session->hang_up_button),
label_hbox);
gtk_widget_show(label_hbox);
/* pick up button symbol*/
/* style = gtk_widget_get_style(session->main_window); */
/* (already done for pickup button) */
pixmap = gdk_pixmap_create_from_xpm_d(session->main_window->window,
&mask,
&style->bg[GTK_STATE_NORMAL],
(gchar **) hangup_xpm);
pixmapwid = gtk_pixmap_new(pixmap, mask);
gtk_box_pack_start(GTK_BOX(label_hbox), pixmapwid, FALSE, FALSE, 2);
gtk_widget_show(pixmapwid);
/* hang up button label */
session->hang_up_label = gtk_label_new(NULL);
gtk_box_pack_start(GTK_BOX(label_hbox), session->hang_up_label,
TRUE, FALSE, 16); /* expand but fill up outside label */
gtk_widget_show(session->hang_up_label);
return frame;
}
/*
* main function for gtk GUI
*
* returns int to be returned from main()
*/
int main_gtk(session_t *session) {
GList* icon_list = NULL;
GtkWidget *main_window;
GtkWidget *main_vbox;
GtkWidget *main_menu;
GtkWidget *dialbox;
GtkWidget *cidbox;
GtkWidget *dummy_label; /* needed to calculate the length of a text label */
GtkRequisition requisition;
GtkRcStyle *rc_style;
GdkColor color;
/* the main window */
session->main_window = main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(main_window), "ANT " VERSION);
/* seems to cause window managers only to use the first one as icon (e.g.FVWM)
icon_list = g_list_append(icon_list,
(gpointer) gdk_pixbuf_new_from_xpm_data((const char**) icon16x16));
icon_list = g_list_append(icon_list,
(gpointer) gdk_pixbuf_new_from_xpm_data((const char**) icon32x32));
*/
icon_list = g_list_append(icon_list,
(gpointer) gdk_pixbuf_new_from_xpm_data((const char**) icon48x48));
/*
icon_list = g_list_append(icon_list,
(gpointer) gdk_pixbuf_new_from_xpm_data((const char**) icon64x64));
*/
gtk_window_set_icon_list(GTK_WINDOW(session->main_window), icon_list);
gtk_signal_connect(GTK_OBJECT(main_window), "delete_event",
GTK_SIGNAL_FUNC(delete_event), (gpointer) session);
gtk_container_set_border_width(GTK_CONTAINER(main_window), 0);
gtk_widget_realize(main_window);
gtk_object_set(GTK_OBJECT(main_window), "allow_shrink", FALSE, NULL);
gtk_object_set(GTK_OBJECT(main_window), "allow_grow", TRUE, NULL);
/* set some defaults */
gtk_hbutton_box_set_spacing_default(16); /* space between buttons */
gtk_hbutton_box_set_layout_default(GTK_BUTTONBOX_SPREAD);
/* main vbox */
main_vbox = gtk_vbox_new(FALSE, 0); /* not homogeneous, spacing = 0 */
gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
gtk_container_add(GTK_CONTAINER(main_window), main_vbox);
gtk_widget_show(main_vbox);
/* contents of main vbox (wrong order to let menu depend on others): */
/* the dial hbox */
dialbox = get_dial_box(session);
gtk_widget_show(dialbox);
/* key pad */
session->controlpad = controlpad_new(session); /* show later */
/* the caller id section */
cidbox = cid_new(session); /* show later */
/* status bar */
session->status_bar = gtk_statusbar_new();
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(session->status_bar), FALSE);
gtk_widget_show(session->status_bar);
session->phone_context_id =
gtk_statusbar_get_context_id(GTK_STATUSBAR(session->status_bar), "phone");
gtk_statusbar_push(GTK_STATUSBAR(session->status_bar),
session->phone_context_id, "");
/* line level check inside status bar */
session->llcheck = gtk_vbox_new(FALSE, 0);
gtk_box_pack_end(GTK_BOX(session->status_bar),
session->llcheck, FALSE, FALSE, 0);
session->llcheck_in =
llcheck_bar_new(66, 10, 0, 200, 0);
gtk_box_pack_start(GTK_BOX(session->llcheck),
session->llcheck_in, FALSE, FALSE, 0);
gtk_widget_show(session->llcheck_in);
session->llcheck_out =
llcheck_bar_new(66, 10, 200, 0, 0);
gtk_box_pack_start(GTK_BOX(session->llcheck),
session->llcheck_out, FALSE, FALSE, 0);
gtk_widget_show(session->llcheck_out);
/* audio warning inside status bar */
session->audio_warning = gtk_statusbar_new();
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(session->audio_warning),
FALSE);
gdk_color_parse("#B00000", &color);
rc_style = gtk_rc_style_new();
rc_style->fg[GTK_STATE_NORMAL] = color;
rc_style->color_flags[GTK_STATE_NORMAL] |= GTK_RC_FG;
gtk_widget_modify_style(GTK_STATUSBAR(session->audio_warning)->label,
rc_style);
gtk_rc_style_unref(rc_style);
gtk_box_pack_end(GTK_BOX(session->status_bar),
session->audio_warning, FALSE, FALSE, 0);
session->audio_context_id =
gtk_statusbar_get_context_id(GTK_STATUSBAR(session->audio_warning),
"audio");
gtk_statusbar_push(GTK_STATUSBAR(session->audio_warning),
session->audio_context_id, "");
/* mute warning inside status bar */
session->muted_warning = gtk_statusbar_new();
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(session->muted_warning),
FALSE);
gdk_color_parse("#008000", &color);
rc_style = gtk_rc_style_new();
rc_style->fg[GTK_STATE_NORMAL] = color;
rc_style->color_flags[GTK_STATE_NORMAL] |= GTK_RC_FG;
gtk_widget_modify_style(GTK_STATUSBAR(session->muted_warning)->label,
rc_style);
gtk_rc_style_unref(rc_style);
gtk_box_pack_end(GTK_BOX(session->status_bar),
session->muted_warning, FALSE, FALSE, 0);
session->muted_context_id =
gtk_statusbar_get_context_id(GTK_STATUSBAR(session->muted_warning),
"muted");
gtk_statusbar_push(GTK_STATUSBAR(session->muted_warning),
session->muted_context_id, _("MUTED"));
dummy_label = gtk_label_new(_("MUTED"));
gtk_widget_show(dummy_label);
gtk_widget_size_request(dummy_label, &requisition);
gtk_widget_set_size_request(session->muted_warning,
requisition.width + 4, -1);
/* main menu bar */
main_menu = get_main_menu(main_window, session); /* main menu */
gtk_widget_show(main_menu);
/* pack items into main vbox (after main menu bar creation) */
gtk_box_pack_start(GTK_BOX(main_vbox), main_menu, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(main_vbox), dialbox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(main_vbox), session->controlpad, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(main_vbox), cidbox, TRUE, TRUE, 0);
gtk_box_pack_end(GTK_BOX(main_vbox), session->status_bar, FALSE, FALSE, 2);
/* show items on demand */
if (GTK_CHECK_MENU_ITEM(session->controlpad_check_menu_item)->active)
gtk_widget_show(session->controlpad);
if (GTK_CHECK_MENU_ITEM(session->cid_check_menu_item)->active)
gtk_widget_show(cidbox);
if (GTK_CHECK_MENU_ITEM(session->llcheck_check_menu_item)->active)
gtk_widget_show(session->llcheck);
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(session->mute_button)))
gtk_widget_show(session->muted_warning);
/* show everything */
gtk_widget_show(main_window);
settings_history_read(session); /* get history from home dir dotfile */
gtk_clist_freeze(GTK_CLIST(session->cid_list));
settings_callerid_read(session); /* get callerid history */
if (session->option_calls_merge)
cid_calls_merge(session); /* merge history from isdnlog */
gtk_clist_thaw(GTK_CLIST(session->cid_list));
cid_jump_to_end(session);
cid_jump_to_end(session);
/* connect isdn and sound input handlers to gdk pseudo select */
session_io_handlers_start(session);
/* set up for initial state */
session_set_state(session, STATE_READY); /* state is already in session */
/* set up additional handlers */
gtk_timeout_add(TIMER_DELAY, timeout_callback, (gpointer) session);
signal(SIGINT, &terminate_signal_callback);
signal(SIGTERM, &terminate_signal_callback);
/* gtk main loop */
gtk_main();
/* some deinit */
session_io_handlers_stop(session);
return 0;
}

30
src/gtk.h Normal file
View File

@ -0,0 +1,30 @@
/*
* gtk GUI functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* own header files */
#include "session.h"
GtkWidget *ok_dialog_get(char *title, char *contents,
GtkJustification justification);
void show_audio_error_dialog(void);
int main_gtk(session_t *session);

631
src/gtksettings.c Normal file
View File

@ -0,0 +1,631 @@
/*
* settings gtk GUI functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
*/
#include "config.h"
/* regular GNU system includes */
#include <stdio.h>
#include <string.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
/* GTK */
#include <gtk/gtk.h>
/* own header files */
#include "globals.h"
#include "session.h"
#include "isdn.h"
#include "sound.h"
#include "gtk.h"
#include "settings.h"
#include "recording.h"
/*
* Load all settings from widgets into session
* -> used by gtksettings_cb_ok and gtksettings_cb_save
*
* input: widget: the widget with associated data widgets and session inside
*
* returns 0 on success, -1 otherwise (bad audio settings)
*/
static int gtksettings_try(GtkWidget *widget) {
session_t *session = gtk_object_get_data(GTK_OBJECT(widget),
"session");
/* save current settings */
char *old_msn = session->msn;
char *old_msns = session->msns;
int successful = 1;
GtkWidget *entry;
GtkWidget *button;
GSList *list;
/* exec_on_incoming */
entry = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"exec_on_incoming_entry");
if (entry) {
free(session->exec_on_incoming);
session->exec_on_incoming = strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
} else
fprintf(stderr, "gtksettings_cb_ok: Error getting exec_on_incoming.\n");
/* popup checkbutton */
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"popup_checkbutton");
if (button)
session->option_popup =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
else
fprintf(stderr, "gtksettings_cb_ok: Error getting popup state.\n");
/* recording_format */
list = (GSList *) gtk_object_get_data(GTK_OBJECT(widget), "recording_format");
if (list) {
while (list) {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list->data))) {
session->option_recording_format = (enum recording_format_t)
gtk_object_get_data(GTK_OBJECT(list->data), "rec_format");
}
list = list->next;
}
} else
fprintf(stderr, "gtksettings_cb_ok: Error getting recording_format.\n");
/* msn */
entry = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget), "msn_entry");
if (entry)
session->msn = strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
else
fprintf(stderr, "gtksettings_cb_ok: Error getting msn.\n");
/* msns */
entry = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget), "msns_entry");
if (entry)
session->msns = strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
else
fprintf(stderr, "gtksettings_cb_ok: Error getting msns.\n");
/* history_entry */
entry = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"history_entry");
if (entry)
session->dial_number_history_maxlen =
strtol(gtk_entry_get_text(GTK_ENTRY(entry)), NULL, 0);
else
fprintf(stderr, "gtksettings_cb_ok: Error getting history.\n");
session->dial_number_history_pointer = 0;
/* cid_max_entry */
entry = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"cid_max_entry");
if (entry)
session->cid_num_max =
strtol(gtk_entry_get_text(GTK_ENTRY(entry)), NULL, 0);
else
fprintf(stderr, "gtksettings_cb_ok: "
"Error getting caller id maximum rows.\n");
/* cid_calls_merge_checkbutton */
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"cid_calls_merge_checkbutton");
if (button)
session->option_calls_merge =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
else
fprintf(stderr,
"gtksettings_cb_ok: Error getting isdnlog calls_merge state.\n");
/* cid_calls_merge_max_entry */
entry = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"cid_calls_merge_max_entry");
if (entry)
session->option_calls_merge_max_days =
strtol(gtk_entry_get_text(GTK_ENTRY(entry)), NULL, 0);
else
fprintf(stderr, "gtksettings_cb_ok: "
"Error getting maximum number of days for isdnlog retrieval.\n");
/* save checkbutton */
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"save_checkbutton");
if (button)
session->option_save_options =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
else
fprintf(stderr,
"gtksettings_cb_ok: Error getting save_options state.\n");
/*
* audio stop/start
*/
if (session->audio_device_name_in) { /* shut down if defined */
session_io_handlers_stop(session);
if (!session->option_release_devices) /* audio_close if normal mode */
session_audio_deinit(session);
free(session->audio_device_name_in);
free(session->audio_device_name_out);
}
/* audio_device_name_in */
entry = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"audio_device_name_in_entry");
if (entry)
session->audio_device_name_in =
strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
else
fprintf(stderr,"gtksettings_cb_ok: Error getting audio_device_name_in.\n");
/* audio_device_name_out */
entry = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"audio_device_name_out_entry");
if (entry)
session->audio_device_name_out =
strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
else
fprintf(stderr,
"gtksettings_cb_ok: Error getting audio_device_name_out.\n");
/* release checkbutton */
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
"release_checkbutton");
if (button)
session->option_release_devices =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
else
fprintf(stderr,
"gtksettings_cb_ok: Error getting release_devices state.\n");
if (!session->option_release_devices) {
if (session_audio_init(session)) {
successful = 0;
free(session->audio_device_name_in);
free(session->audio_device_name_out);
session->audio_device_name_in = NULL; /* flag for audio shut down */
}
}
if (session->audio_device_name_in) { /* OK or unknown */
session_io_handlers_start(session);
session_set_state(session, STATE_READY); /* update everything */
}
/* try to apply msn settings */
if (isdn_setMSN(session->isdn_fd, session->msn) ||
isdn_setMSNs(session->isdn_fd, session->msns)) {
/* got some problem */
free(session->msn);
free(session->msns);
session->msn = old_msn;
session->msns = old_msns;
isdn_setMSN(session->isdn_fd, session->msn);
isdn_setMSNs(session->isdn_fd, session->msns);
successful = 0;
} else {
/* everything's fine */
free(old_msn);
free(old_msns);
}
return !!successful - 1;
}
/*
* clicked "ok" at gtksettings_cb
* input: window: the widget with associated data widgets and session inside
*/
static void gtksettings_cb_ok(GtkWidget *window) {
GtkWidget *ok_window;
if (!gtksettings_try(window)) { /* changed settings */
gtk_widget_destroy(window);
} else { /* settings error -> restored old settings -> display note */
ok_window = ok_dialog_get(_("ANT Note"),
_("Bad isdn/sound device settings, please try again."),
GTK_JUSTIFY_CENTER);
gtk_window_set_modal(GTK_WINDOW(ok_window), TRUE);
gtk_widget_show(ok_window);
}
}
/* clicked "Save" button at settings dialog (gtksettings_cb) */
static void gtksettings_cb_save(GtkWidget *widget) {
session_t *session = gtk_object_get_data(GTK_OBJECT(widget),
"session");
gtksettings_try(widget);
settings_options_write(session);
}
/* clicked "Cancel" button at settings dialog (gtksettings_cb) */
static void gtksettings_cb_cancel(GtkWidget *window) {
session_t *session = gtk_object_get_data(GTK_OBJECT(window),
"session");
if (session->audio_device_name_in) /* audio not shut off */
gtk_widget_destroy(window);
}
/*
* callback for setting widget sensitivity on toggle button change
*/
static void toggle_sensitive_register(GtkToggleButton *button,
GtkWidget *widget) {
gtk_widget_set_sensitive(widget, gtk_toggle_button_get_active(button));
}
/* Settings menu entry callback */
void gtksettings_cb(GtkWidget *widget _U_, gpointer data, guint action _U_) {
session_t *session = (session_t *) data;
GtkWidget *window; /* the dialog window itself */
GtkWidget *button_box; /* box for buttons in standard way */
GtkWidget *button; /* action area buttons */
GtkWidget *table; /* tables in frames */
GtkWidget *label; /* different labels */
GtkWidget *frame; /* the frames to separate msn/msns from sound devices */
GtkWidget *notebook; /* to separate options into topics */
GtkWidget *vbox; /* the vbox inside notebook with frames */
GtkWidget *vbox2; /* vbox inside frames */
/* widgets to save (to evaluate later) */
GtkWidget *save_checkbutton; /* program page */
GtkWidget *popup_checkbutton;
GtkWidget *exec_on_incoming_entry;
GtkWidget *msn_entry; /* phone page */
GtkWidget *msns_entry;
GtkWidget *history_entry;
GtkWidget *cid_max_entry;
GtkWidget *audio_device_name_in_entry; /* sound devices page */
GtkWidget *audio_device_name_out_entry;
GtkWidget *release_checkbutton;
GtkWidget *recformat_radiobutton; /* recording format */
GtkWidget *cid_calls_merge_checkbutton;
GtkWidget *cid_calls_merge_max_entry;
char *s; /* temporary string */
window = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(window), _("ANT Settings"));
/* the notebook inside the window / vbox area */
notebook = gtk_notebook_new();
gtk_container_set_border_width(GTK_CONTAINER(notebook), 5);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), notebook,
TRUE, TRUE, 0);
gtk_widget_show(notebook);
/* Program page */
vbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(vbox);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox,
gtk_label_new(_("Application")));
frame = gtk_frame_new(_("Options"));
gtk_container_set_border_width(GTK_CONTAINER(frame), 10);
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
gtk_widget_show(frame);
table = gtk_table_new(3, 2, FALSE); /* rows, columns, not homogeneous */
gtk_container_add(GTK_CONTAINER(frame), table);
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_table_set_col_spacings(GTK_TABLE(table), 5);
gtk_widget_show(table);
save_checkbutton = gtk_check_button_new_with_label(_("Save options on exit"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(save_checkbutton),
session->option_save_options);
gtk_table_attach_defaults(GTK_TABLE(table), save_checkbutton, 0,2,0,1);
gtk_widget_show(save_checkbutton);
popup_checkbutton =
gtk_check_button_new_with_label(_("Popup main window on incoming call"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(popup_checkbutton),
session->option_popup);
gtk_table_attach_defaults(GTK_TABLE(table), popup_checkbutton, 0,2,1,2);
gtk_widget_show(popup_checkbutton);
label = gtk_label_new(_("Execute on incoming call:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0,1,2,3);
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_widget_show(label);
exec_on_incoming_entry = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table), exec_on_incoming_entry, 1,2,2,3);
gtk_entry_set_text(GTK_ENTRY(exec_on_incoming_entry),
session->exec_on_incoming);
gtk_widget_show(exec_on_incoming_entry);
frame = gtk_frame_new(_("Recording Format"));
gtk_container_set_border_width(GTK_CONTAINER(frame), 10);
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
gtk_widget_show(frame);
vbox2 = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox2);
gtk_widget_show(vbox2);
recformat_radiobutton = gtk_radio_button_new_with_label(NULL,
_("Microsoft WAV, uLaw"));
gtk_box_pack_start(GTK_BOX(vbox2), recformat_radiobutton, FALSE, FALSE, 0);
gtk_widget_show(recformat_radiobutton);
gtk_object_set_data(GTK_OBJECT(recformat_radiobutton),
"rec_format", (gpointer) (RECORDING_FORMAT_WAV | RECORDING_FORMAT_ULAW));
if (session->option_recording_format == (enum recording_format_t)
gtk_object_get_data(GTK_OBJECT(recformat_radiobutton), "rec_format"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(recformat_radiobutton),TRUE);
recformat_radiobutton = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(recformat_radiobutton), _("Microsoft WAV, 16-bit signed"));
gtk_box_pack_start(GTK_BOX(vbox2), recformat_radiobutton, FALSE, FALSE, 0);
gtk_widget_show(recformat_radiobutton);
gtk_object_set_data(GTK_OBJECT(recformat_radiobutton),
"rec_format", (gpointer) (RECORDING_FORMAT_WAV | RECORDING_FORMAT_S16));
if (session->option_recording_format == (enum recording_format_t)
gtk_object_get_data(GTK_OBJECT(recformat_radiobutton), "rec_format"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(recformat_radiobutton),TRUE);
recformat_radiobutton = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(recformat_radiobutton), _("Apple/SGI AIFF, uLaw"));
gtk_box_pack_start(GTK_BOX(vbox2), recformat_radiobutton, FALSE, FALSE, 0);
gtk_widget_show(recformat_radiobutton);
gtk_object_set_data(GTK_OBJECT(recformat_radiobutton),
"rec_format", (gpointer) (RECORDING_FORMAT_AIFF | RECORDING_FORMAT_ULAW));
if (session->option_recording_format == (enum recording_format_t)
gtk_object_get_data(GTK_OBJECT(recformat_radiobutton), "rec_format"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(recformat_radiobutton),TRUE);
recformat_radiobutton = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(recformat_radiobutton), _("Apple/SGI AIFF, 16-bit signed"));
gtk_box_pack_start(GTK_BOX(vbox2), recformat_radiobutton, FALSE, FALSE, 0);
gtk_widget_show(recformat_radiobutton);
gtk_object_set_data(GTK_OBJECT(recformat_radiobutton),
"rec_format", (gpointer) (RECORDING_FORMAT_AIFF | RECORDING_FORMAT_S16));
if (session->option_recording_format == (enum recording_format_t)
gtk_object_get_data(GTK_OBJECT(recformat_radiobutton), "rec_format"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(recformat_radiobutton),TRUE);
/* Phone page */
vbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(vbox);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox,
gtk_label_new(_("Phone")));
frame = gtk_frame_new(_("ISDN"));
gtk_container_set_border_width(GTK_CONTAINER(frame), 10);
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
gtk_widget_show(frame);
table = gtk_table_new(2, 2, FALSE); /* rows, columns, not homogeneous */
gtk_container_add(GTK_CONTAINER(frame), table);
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_table_set_col_spacings(GTK_TABLE(table), 5);
gtk_widget_show(table);
label = gtk_label_new(_("Identifying MSN:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0,1,0,1);
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_widget_show(label);
msn_entry = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table), msn_entry, 1,2,0,1);
gtk_entry_set_text(GTK_ENTRY(msn_entry), session->msn);
gtk_widget_show(msn_entry);
label = gtk_label_new(_("Listen to MSNs:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0,1,1,2);
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_widget_show(label);
msns_entry = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table), msns_entry, 1,2,1,2);
gtk_entry_set_text(GTK_ENTRY(msns_entry), session->msns);
gtk_widget_show(msns_entry);
frame = gtk_frame_new(_("Dialing"));
gtk_container_set_border_width(GTK_CONTAINER(frame), 10);
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
gtk_widget_show(frame);
table = gtk_table_new(1, 2, FALSE); /* rows, columns, not homogeneous */
gtk_container_add(GTK_CONTAINER(frame), table);
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_table_set_col_spacings(GTK_TABLE(table), 5);
gtk_widget_show(table);
label = gtk_label_new(_("Dial history size:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0,1,0,1);
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_widget_show(label);
history_entry = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table), history_entry, 1,2,0,1);
asprintf(&s, "%u", session->dial_number_history_maxlen);
gtk_entry_set_text(GTK_ENTRY(history_entry), s);
free(s);
gtk_widget_show(history_entry);
frame = gtk_frame_new(_("Caller ID"));
gtk_container_set_border_width(GTK_CONTAINER(frame), 10);
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
gtk_widget_show(frame);
table = gtk_table_new(3, 2, FALSE); /* rows, columns, not homogeneous */
gtk_container_add(GTK_CONTAINER(frame), table);
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_table_set_col_spacings(GTK_TABLE(table), 5);
gtk_widget_show(table);
label = gtk_label_new(_("Maximum CID rows:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0,1,0,1);
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_widget_show(label);
cid_max_entry = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table), cid_max_entry, 1,2,0,1);
if (session->cid_num_max == 0) {
s = strdup(_("[no limit]"));
} else {
asprintf(&s, "%u", session->cid_num_max);
}
gtk_entry_set_text(GTK_ENTRY(cid_max_entry), s);
free(s);
gtk_widget_show(cid_max_entry);
cid_calls_merge_checkbutton = gtk_check_button_new_with_label(
_("Read isdnlog data on startup"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cid_calls_merge_checkbutton),
session->option_calls_merge);
gtk_table_attach_defaults(GTK_TABLE(table), cid_calls_merge_checkbutton,
0,2,1,2);
gtk_widget_show(cid_calls_merge_checkbutton);
label = gtk_label_new(_("Maximum days to read from isdnlog:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0,1,2,3);
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_widget_set_sensitive(label, session->option_calls_merge);
gtk_signal_connect(GTK_OBJECT(cid_calls_merge_checkbutton), "toggled",
GTK_SIGNAL_FUNC(toggle_sensitive_register), label);
gtk_widget_show(label);
cid_calls_merge_max_entry = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table), cid_calls_merge_max_entry,
1,2,2,3);
if (session->option_calls_merge_max_days == 0) {
s = strdup(_("[no limit]"));
} else {
asprintf(&s, "%u", session->option_calls_merge_max_days);
}
gtk_entry_set_text(GTK_ENTRY(cid_calls_merge_max_entry), s);
free(s);
gtk_widget_set_sensitive(cid_calls_merge_max_entry,
session->option_calls_merge);
gtk_signal_connect(GTK_OBJECT(cid_calls_merge_checkbutton), "toggled",
GTK_SIGNAL_FUNC(toggle_sensitive_register),
cid_calls_merge_max_entry);
gtk_widget_show(cid_calls_merge_max_entry);
/* Sound devices page */
vbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(vbox);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox,
gtk_label_new(_("Sound Devices")));
frame = gtk_frame_new(_("OSS"));
gtk_container_set_border_width(GTK_CONTAINER(frame), 10);
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
gtk_widget_show(frame);
table = gtk_table_new(3,2, FALSE); /* rows, columns, not homogeneous */
gtk_container_add(GTK_CONTAINER(frame), table);
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_table_set_col_spacings(GTK_TABLE(table), 5);
gtk_widget_show(table);
label = gtk_label_new(_("Input sound device:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0,1,0,1);
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_widget_show(label);
audio_device_name_in_entry = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table), audio_device_name_in_entry,
1,2,0,1);
gtk_entry_set_text(GTK_ENTRY(audio_device_name_in_entry),
session->audio_device_name_in);
gtk_widget_show(audio_device_name_in_entry);
label = gtk_label_new(_("Output sound device:"));
gtk_table_attach_defaults(GTK_TABLE(table), label, 0,1,1,2);
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_widget_show(label);
audio_device_name_out_entry = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table), audio_device_name_out_entry,
1,2,1,2);
gtk_entry_set_text(GTK_ENTRY(audio_device_name_out_entry),
session->audio_device_name_out);
gtk_widget_show(audio_device_name_out_entry);
release_checkbutton =
gtk_check_button_new_with_label(_("Release unused devices"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(release_checkbutton),
session->option_release_devices);
gtk_table_attach_defaults(GTK_TABLE(table), release_checkbutton, 0,2,2,3);
gtk_widget_show(release_checkbutton);
/* action area */
button_box = gtk_hbutton_box_new();
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->action_area),
button_box);
gtk_widget_show(button_box);
button = gtk_button_new_with_label(_("OK"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_object_set_data(GTK_OBJECT(window), "session", (gpointer) session);
gtk_object_set_data(GTK_OBJECT(window), "save_checkbutton",
(gpointer) save_checkbutton);
gtk_object_set_data(GTK_OBJECT(window), "popup_checkbutton",
(gpointer) popup_checkbutton);
gtk_object_set_data(GTK_OBJECT(window), "exec_on_incoming_entry",
(gpointer) exec_on_incoming_entry);
gtk_object_set_data(GTK_OBJECT(window), "recording_format",
(gpointer) gtk_radio_button_group(GTK_RADIO_BUTTON(recformat_radiobutton)));
gtk_object_set_data(GTK_OBJECT(window), "msn_entry", (gpointer) msn_entry);
gtk_object_set_data(GTK_OBJECT(window), "msns_entry", (gpointer) msns_entry);
gtk_object_set_data(GTK_OBJECT(window), "history_entry",
(gpointer) history_entry);
gtk_object_set_data(GTK_OBJECT(window), "cid_max_entry",
(gpointer) cid_max_entry);
gtk_object_set_data(GTK_OBJECT(window), "cid_calls_merge_checkbutton",
(gpointer) cid_calls_merge_checkbutton);
gtk_object_set_data(GTK_OBJECT(window), "cid_calls_merge_max_entry",
(gpointer) cid_calls_merge_max_entry);
gtk_object_set_data(GTK_OBJECT(window), "audio_device_name_in_entry",
(gpointer) audio_device_name_in_entry);
gtk_object_set_data(GTK_OBJECT(window), "audio_device_name_out_entry",
(gpointer) audio_device_name_out_entry);
gtk_object_set_data(GTK_OBJECT(window), "release_checkbutton",
(gpointer) release_checkbutton);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(gtksettings_cb_ok),
GTK_OBJECT(window));
gtk_widget_show(button);
button = gtk_button_new_with_label(_("Save"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(gtksettings_cb_save),
GTK_OBJECT(window));
gtk_widget_show(button);
button = gtk_button_new_with_label(_("Cancel"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(gtksettings_cb_cancel),
GTK_OBJECT(window));
gtk_signal_connect_object(GTK_OBJECT(window), "delete_event",
GTK_SIGNAL_FUNC(gtksettings_cb_cancel),
GTK_OBJECT(window));
gtk_widget_show(button);
gtk_window_set_modal(GTK_WINDOW(window), TRUE);
/* show everything */
gtk_widget_show(window);
}

17
src/gtksettings.h Normal file
View File

@ -0,0 +1,17 @@
/*
* gtk GUI functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
*/
/* GTK */
#include <gtk/gtk.h>
/* own header files */
#include "session.h"
void gtksettings_cb_ok(GtkWidget *widget, gpointer data);
void gtksettings_cb(GtkWidget *widget _U_, gpointer data, guint action _U_);

19
src/hangup.xpm Normal file
View File

@ -0,0 +1,19 @@
/* XPM */
static char * hangup_xpm[] = {
"16 14 2 1",
" c None",
". c #E20000",
" .. ",
" .. ",
" .. ",
" . .. . ",
" ...... ",
" .... ",
" .. ",
" ",
" ",
" ............ ",
" .............. ",
"..... .....",
"..... ....",
" .. .. "};

108
src/icon16x16.xpm Normal file
View File

@ -0,0 +1,108 @@
/* XPM */
static char *icon16x16[] = {
/* columns rows colors chars-per-pixel */
"16 16 86 1",
" c black",
". c #000100",
"X c #010101",
"o c #010201",
"O c #020302",
"+ c #040504",
"@ c #050605",
"# c #0B0C0B",
"$ c #0D0E0D",
"% c #0E0F0E",
"& c gray6",
"* c #111111",
"= c #131313",
"- c gray8",
"; c #141514",
": c #151615",
"> c #181818",
", c #191A19",
"< c gray10",
"1 c #1C1D1C",
"2 c gray13",
"3 c #262726",
"4 c #2C2C2C",
"5 c #2C2D2C",
"6 c #333433",
"7 c #343534",
"8 c #353635",
"9 c #373837",
"0 c gray22",
"q c #3A3B3A",
"w c #3C3D3C",
"e c #414241",
"r c #454645",
"t c gray28",
"y c #484948",
"u c #4E4E4E",
"i c #535453",
"p c #5A5B5A",
"a c #5D5E5D",
"s c gray37",
"d c #646564",
"f c #656565",
"g c #6D6E6D",
"h c #6E6F6E",
"j c #6F706F",
"k c #747474",
"l c #797979",
"z c #868686",
"x c gray55",
"c c #8E8F8E",
"v c #959595",
"b c gray59",
"n c #999A99",
"m c #A6A7A6",
"M c gray66",
"N c #A8A9A8",
"B c gray71",
"V c #B6B6B6",
"C c gray72",
"Z c #C0C0C0",
"A c #C3C3C3",
"S c #C5C5C5",
"D c gray78",
"F c #CBCBCB",
"G c gray82",
"H c #D2D2D2",
"J c gray84",
"K c #D7D7D7",
"L c #D8D8D8",
"P c gainsboro",
"I c gray88",
"U c #E1E1E1",
"Y c gray89",
"T c #E6E6E6",
"R c #E7E7E7",
"E c #E9E9E9",
"W c #EAEAEA",
"Q c gray94",
"! c #F1F1F1",
"~ c #F3F3F3",
"^ c gray96",
"/ c gray97",
"( c gray99",
") c #FDFDFD",
"_ c #FEFEFE",
"` c gray100",
/* pixels */
"````````````````",
"````````````````",
"````````````````",
"```RJ```````````",
"``t 0sF(Q``````",
"`^= ,: 2uRQ`^xx`",
"``FbLYmBlKY`C g~",
"D,#: i=65: y@ 9",
"AzQ~8 @%Y`e b j^",
"Hp33: 6``d b k`",
"5#R`q +8``d n j`",
"s yw1 8``d B@%y",
"`ZmKWDDF``LD^LMA",
"````````````````",
"````````````````",
"````````````````"
};

190
src/icon32x32.xpm Normal file
View File

@ -0,0 +1,190 @@
/* XPM */
static char *icon32x32[] = {
/* columns rows colors chars-per-pixel */
"32 32 152 2",
" c black",
". c #000100",
"X c #010101",
"o c #010201",
"O c gray1",
"+ c #030403",
"@ c #040404",
"# c #040504",
"$ c #070807",
"% c #080908",
"& c #090909",
"* c #0C0D0C",
"= c #0D0E0D",
"- c #0F100F",
"; c #111111",
": c #121312",
"> c #141514",
", c #181918",
"< c #191A19",
"1 c #1A1B1A",
"2 c gray11",
"3 c #1C1D1C",
"4 c #1D1E1D",
"5 c #1F201F",
"6 c #212221",
"7 c gray14",
"8 c #262726",
"9 c #2C2D2C",
"0 c #2E2F2E",
"q c #303130",
"w c #333433",
"e c #343534",
"r c #353635",
"t c #373837",
"y c gray22",
"u c #383938",
"i c #393A39",
"p c #3C3C3C",
"a c #3C3D3C",
"s c #3F3F3F",
"d c gray25",
"f c #414241",
"g c #474847",
"h c #4C4C4C",
"j c gray30",
"k c #4E4E4E",
"l c #505050",
"z c #505150",
"x c gray32",
"c c #525352",
"v c #535453",
"b c #555555",
"n c #555655",
"m c #565756",
"M c gray36",
"N c #5D5E5D",
"B c #5E5F5E",
"V c #5F5F5F",
"C c #606060",
"Z c #626362",
"A c gray39",
"S c #656565",
"D c gray40",
"F c #676767",
"G c #676867",
"H c #696A69",
"J c #6A6A6A",
"K c #6E6F6E",
"L c #717171",
"P c #767776",
"I c #777777",
"U c gray47",
"Y c gray48",
"T c #808080",
"R c gray51",
"E c #838383",
"W c gray52",
"Q c #858685",
"! c gray53",
"~ c #888988",
"^ c #898989",
"/ c #8A8B8A",
"( c gray56",
") c #909090",
"_ c #909190",
"` c #929392",
"' c #959595",
"] c #9D9D9D",
"[ c #A0A1A0",
"{ c #A2A2A2",
"} c gray64",
"| c #A4A5A4",
" . c #A5A5A5",
".. c #A5A6A5",
"X. c #A7A7A7",
"o. c #A7A8A7",
"O. c gray66",
"+. c #AAAAAA",
"@. c gray67",
"#. c #ABACAB",
"$. c gray68",
"%. c #AFAFAF",
"&. c gray69",
"*. c #B3B4B3",
"=. c gray71",
"-. c #B7B7B7",
";. c gray72",
":. c #BBBBBB",
">. c gray75",
",. c gray76",
"<. c gray77",
"1. c #C4C5C4",
"2. c #C8C8C8",
"3. c #CACACA",
"4. c gray80",
"5. c #CDCDCD",
"6. c #CDCECD",
"7. c gray81",
"8. c gray82",
"9. c gray84",
"0. c #D7D7D7",
"q. c gray85",
"w. c #DADADA",
"e. c gainsboro",
"r. c gray87",
"t. c #DFDFDF",
"y. c gray88",
"u. c #E1E1E1",
"i. c #E2E2E2",
"p. c gray89",
"a. c #E4E4E4",
"s. c gray90",
"d. c #E5E6E5",
"f. c #E6E6E6",
"g. c #E6E7E6",
"h. c #E7E7E7",
"j. c gray91",
"k. c #E9E9E9",
"l. c gray92",
"z. c #EEEEEE",
"x. c #F1F1F1",
"c. c gray95",
"v. c #F3F3F3",
"b. c #F4F4F4",
"n. c gray96",
"m. c #F6F6F6",
"M. c gray97",
"N. c gray98",
"B. c gray99",
"V. c #FDFDFD",
"C. c #FEFEFE",
"Z. c gray100",
/* pixels */
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.f.-.} ;.b.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.3.d . . . . 7 :.&.2.Z.Z.Z.Z.Z.j.b.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.b.; . . . . . . . . . p x.Z.b.f.b.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.y.. . . . . . . . . . . E ( +.f.y.r.j.Z.Z.Z.Z.Z.q.H j.Z.Z.",
"Z.Z.Z.Z.h . . . @ A l . . . . . . . r.Z.Z.Z.Z.Z.Z.9.c + . j.Z.Z.",
"Z.Z.Z.Z.Z.>.E ^ 5.m.Z.+.V L U ] . 2 m.Z.Z.Z.Z.Z.Z.! . . . j.Z.Z.",
"Z.Z.Z.x.<.+.} +.&.l.Z.r.j.y.7.x.y.f.,.X.%.0.Z.Z.y.Y . . . 5.y.z.",
"Z.z.V $ . . . + @ @ k 5.6 . # %.! ; . . . . r 8.= . . . . . . K ",
"N.r . . + q a 5 . . . r 6 . . 4 . , a , . . . 4 & . . . . . . K ",
"7.a , & ,.Z.Z.Z.H . . . = . . . _ Z.Z.N.c . . . +.Y . . . 8.f.x.",
"Z.Z.Z.b.Z.Z.Z.q.H . . . . . . p Z.Z.Z.Z.*.. . . +.! . . . j.Z.Z.",
"Z.Z.q.) V w = . . . . . . . . A Z.Z.Z.Z.2.. . . } ! . . . j.Z.Z.",
"b.b . . . $ 0 M c . . . # . . H Z.Z.Z.Z.3.. . . } ^ . . . j.Z.Z.",
"I . . # } b.Z.Z.` . . . # . . H Z.Z.Z.Z.3.. . . } ^ . . . f.Z.Z.",
"p . . 8 Z.Z.Z.Z.b . . . # . . H Z.Z.Z.Z.3.. . . } ` . . . q.Z.Z.",
"A . . . C -.} g . . . . . . . H Z.Z.Z.Z.3.. . . +.} . . . r V E ",
"f.0 . . . . . @ S = . . . . . H Z.Z.Z.Z.3.. . . } j.> . . . . d ",
"Z.N.] A k b ! q.Z.+./ ^ / / ^ >.Z.Z.Z.Z.h.^ / ^ q.Z.y.E c k S } ",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.",
"Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z."
};

256
src/icon48x48.xpm Normal file
View File

@ -0,0 +1,256 @@
/* XPM */
static char *icon48x48[] = {
/* columns rows colors chars-per-pixel */
"48 48 202 2",
" c black",
". c #000100",
"X c #010101",
"o c #010201",
"O c #020202",
"+ c #020302",
"@ c gray1",
"# c #030403",
"$ c #040404",
"% c #040504",
"& c gray2",
"* c #050605",
"= c #060606",
"- c #060706",
"; c #070707",
": c #070807",
"> c gray3",
", c #080908",
"< c #090909",
"1 c #0B0B0B",
"2 c #0C0C0C",
"3 c #0C0D0C",
"4 c #0D0E0D",
"5 c #0E0E0E",
"6 c #0E0F0E",
"7 c #0F100F",
"8 c #101110",
"9 c #111211",
"0 c gray7",
"q c #131413",
"w c gray8",
"e c #141514",
"r c #171817",
"t c #181918",
"y c #191A19",
"u c gray11",
"i c #1C1D1C",
"p c #1E1F1E",
"a c #202120",
"s c #212221",
"d c #222222",
"f c gray14",
"g c gray16",
"h c #2B2C2B",
"j c #2C2C2C",
"k c #2C2D2C",
"l c #2D2E2D",
"z c #2E2F2E",
"x c #2F302F",
"c c #313131",
"v c #313231",
"b c #323332",
"n c #343434",
"m c #353635",
"M c #373837",
"N c gray22",
"B c #393939",
"V c #393A39",
"C c gray23",
"Z c gray24",
"A c #3E3F3E",
"S c #404140",
"D c #434343",
"F c #434443",
"G c gray27",
"H c #454645",
"J c gray29",
"K c #4B4C4B",
"L c #4C4C4C",
"P c #4C4D4C",
"I c #4E4F4E",
"U c gray31",
"Y c #4F504F",
"T c #505150",
"R c #515251",
"E c gray32",
"W c #525352",
"Q c #535453",
"! c gray33",
"~ c #565756",
"^ c gray35",
"/ c #5A5A5A",
"( c #5A5B5A",
") c #5B5B5B",
"_ c #5C5D5C",
"` c gray37",
"' c #5F5F5F",
"] c gray39",
"[ c gray40",
"{ c DimGray",
"} c #696A69",
"| c #6A6B6A",
" . c #6D6D6D",
".. c gray43",
"X. c #707170",
"o. c #717171",
"O. c #727272",
"+. c #747474",
"@. c gray46",
"#. c #757675",
"$. c #777777",
"%. c gray47",
"&. c #787978",
"*. c #797A79",
"=. c #7A7B7A",
"-. c #7C7C7C",
";. c #7C7D7C",
":. c gray49",
">. c #7E7E7E",
",. c #7F807F",
"<. c #808080",
"1. c #838383",
"2. c #848484",
"3. c #868686",
"4. c gray53",
"5. c #888988",
"6. c #8B8B8B",
"7. c #8D8E8D",
"8. c gray56",
"9. c #949594",
"0. c #959595",
"q. c gray59",
"w. c #969796",
"e. c #979797",
"r. c gray60",
"t. c #9A9A9A",
"y. c #9B9B9B",
"u. c gray62",
"i. c #9F9F9F",
"p. c #A2A2A2",
"a. c gray64",
"s. c #A4A5A4",
"d. c #A5A5A5",
"f. c #A6A7A6",
"g. c #AAAAAA",
"h. c #ACACAC",
"j. c gray68",
"k. c #AEAEAE",
"l. c #AFAFAF",
"z. c gray69",
"x. c #B2B2B2",
"c. c gray70",
"v. c #B4B4B4",
"b. c gray71",
"n. c #B6B7B6",
"m. c gray72",
"M. c #B9B9B9",
"N. c #B9BAB9",
"B. c #BBBBBB",
"V. c gray74",
"C. c gray76",
"Z. c #C3C3C3",
"A. c gray78",
"S. c gray79",
"D. c #CACACA",
"F. c #CBCBCB",
"G. c #CDCDCD",
"H. c gray81",
"J. c #D0D0D0",
"K. c gray82",
"L. c LightGray",
"P. c gray83",
"I. c #D5D5D5",
"U. c gray84",
"Y. c #D7D7D7",
"T. c gray85",
"R. c #DADADA",
"E. c gray86",
"W. c #DDDDDD",
"Q. c #DDDEDD",
"!. c #DFDFDF",
"~. c gray88",
"^. c #E1E1E1",
"/. c #E2E2E2",
"(. c #E2E3E2",
"). c gray89",
"_. c #E4E4E4",
"`. c gray90",
"'. c #E7E7E7",
"]. c gray91",
"[. c gray92",
"{. c #ECECEC",
"}. c gray93",
"|. c #EEEEEE",
" X c #EFEFEF",
".X c gray94",
"XX c #F1F1F1",
"oX c gray95",
"OX c #F3F3F3",
"+X c #F4F4F4",
"@X c gray96",
"#X c gray97",
"$X c #F7F8F7",
"%X c #F8F8F8",
"&X c #F9F9F9",
"*X c gray98",
"=X c #FBFBFB",
"-X c gray99",
";X c #FDFDFD",
":X c #FEFEFE",
">X c #FEFFFE",
",X c gray100",
/* pixels */
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X'.x.6.$.$.p.|.,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,Xm.G & e g.,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X:. & c & 2 C d.,X,X,X,X,X|.G.K.[.,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X'.& 1.,X,X,X'.[.,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,XD. > !.!.m.'.,X*XK.K.G.!.,X,X,X,X,X,X,X,X,Xv.w.,X,X,X,X",
",X,X,X,X,X|.> A & C D.I.,X,X,X,X,X,X,X,X,X,X*Xa.x ' ,X,X,X,X",
",X,X,X,X,X,Xy.> C g.w.i D.,X,X,X,X,X,X,X,X,X,Xa.d ) ,X,X,X,X",
",X,X,X,X,X,X,X!.4.L c / d.[.*X,XW.] d l g f i.) > |.,X,X,X,X,X,X,X,X,X,XJ o ` ,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X|..X,X,X,XW.E.,X,XOX'.!.' D g.,X,X,X,X,X,X,X,X,X,X,XK o _ ,X,X,X,X",
",X,X,X,X,X!.x.8.:.$.&.3.5.N.|.,X,XK._.I.L.I.n.,X,X,X{.x.3.$.:.y.L.,X,X,XY.L.A o o o P L.L.L.|.",
",X,X,Xg.m o : o : ! K.W.b : e =X!.` : o x x.,Xe o o o o d.",
",X,Xo. o o & o o > m.b o e f.7 o o o o y.e o o o o d.",
",Xy. o f Q ` Y p o o x c o o o o m ) Y e o o 7 : o o o o o f.",
"$Xi o 1.=X,X,X,X,X$. o o o p o o C I.,X,X,X.XY o o 8.R.D o L R.R.R..X",
",X.XI.g.7.:.,X,X,X,X,X,X`. o o o o o o y .X,X,X,X,X,X'.& o o 5.,XK o ) ,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X|.N.$.o o o o o | ,X,X,X,X,X,X,Xe o o $.,XK o ' ,X,X,X,X",
",X,X,X,X@XD.w. .H p o o o o o 8.,X,X,X,X,X,X,Xh o o $.,XK o ' ,X,X,X,X",
",X,XG.) 9 o o o o o i.,X,X,X,X,X,X,Xx o o &.,XK o ` ,X,X,X,X",
",Xw.o o 7 C [ w.v.o o o : o o o i.,X,X,X,X,X,X,Xx o o &.,XK o o _ ,X,X,X,X",
"D.o o ) F.*X,X,X,X_.o o o o o o p.,X,X,X,X,X,X,Xx o &.,XK o o ) ,X,X,X,X",
"| o b ,X,X,X,X,X,XF. o o : o y.,X,X,X,X,X,X,Xx &.,X~ o o o Y ,X,X,X,X",
"Q o b ,X,X,X,X,X,X' o : o o o i.,X,X,X,X,X,X,Xx &.,X' F ,X,X,X,X",
"=. o o [ [.,X*XZ.K o o i.,X,X,X,X,X,X,Xx o &.,X| o : $.w.| v.",
"!.e o o : r 2 o o o o o o i.,X,X,X,X,X,X,Xx o o &.,Xi. o o o :.",
",XZ.r o , O.6. o o o i.,X,X,X,X,X,X,Xx o o $.,X@Xl o o / ",
",X,X{.3.m 2 2 m 1.W.,X|.W Y Y W Y Y Y W Y B.,X,X,X,X,X,X,XX.Y Q Y Y p.,X,X|.,.l : o e m w.",
",X,X,X,X,X,X@X.X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X*X.X$X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X",
",X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X"
};

316
src/icon64x64.xpm Normal file
View File

@ -0,0 +1,316 @@
/* XPM */
static char *icon64x64[] = {
/* columns rows colors chars-per-pixel */
"64 64 246 2",
" c black",
". c #000100",
"X c #010101",
"o c #010201",
"O c #020202",
"+ c #020302",
"@ c #030403",
"# c #040504",
"$ c gray2",
"% c #050605",
"& c #060606",
"* c #060706",
"= c #070707",
"- c #070807",
"; c #080908",
": c #090909",
"> c #090A09",
", c gray4",
"< c #0A0B0A",
"1 c #0B0C0B",
"2 c #0C0C0C",
"3 c #0C0D0C",
"4 c #0D0E0D",
"5 c #0E0E0E",
"6 c #0E0F0E",
"7 c gray6",
"8 c #0F100F",
"9 c #111111",
"0 c gray7",
"q c #121312",
"w c #141514",
"e c #161616",
"r c gray9",
"t c #171817",
"y c #191919",
"u c #191A19",
"i c #1A1B1A",
"p c #1B1B1B",
"a c #1B1C1B",
"s c gray11",
"d c #1C1D1C",
"f c #1D1E1D",
"g c #1E1F1E",
"h c gray12",
"j c #222222",
"k c #222322",
"l c #232323",
"z c #232423",
"x c gray14",
"c c #242524",
"v c gray15",
"b c #262726",
"n c #272827",
"m c #2C2C2C",
"M c #2C2D2C",
"N c #2D2E2D",
"B c gray18",
"V c #2E2F2E",
"C c #2F302F",
"Z c #313131",
"A c #323232",
"S c #333433",
"D c #343434",
"F c #343534",
"G c #393A39",
"H c #3F403F",
"J c gray25",
"K c #404140",
"L c #414141",
"P c #434343",
"I c #434443",
"U c #444444",
"Y c gray27",
"T c #454645",
"R c #464646",
"E c gray28",
"W c #484848",
"Q c #494949",
"! c gray29",
"~ c #4B4C4B",
"^ c #4D4E4D",
"/ c #4E4E4E",
"( c gray31",
") c #4F504F",
"_ c #515151",
"` c gray32",
"' c #535453",
"] c gray33",
"[ c #545554",
"{ c #555555",
"} c #565756",
"| c #575857",
" . c #585958",
".. c #595A59",
"X. c #5A5B5A",
"o. c #5B5B5B",
"O. c #5D5E5D",
"+. c gray37",
"@. c #5F5F5F",
"#. c #5F605F",
"$. c #606060",
"%. c #626262",
"&. c #626362",
"*. c #656565",
"=. c #666766",
"-. c #676767",
";. c #686968",
":. c DimGray",
">. c #6A6B6A",
",. c #6B6C6B",
"<. c #6C6C6C",
"1. c #6D6D6D",
"2. c gray43",
"3. c #6F706F",
"4. c #717171",
"5. c #717271",
"6. c #727272",
"7. c gray45",
"8. c #737473",
"9. c #747474",
"0. c gray46",
"q. c #757675",
"w. c #767776",
"e. c gray47",
"r. c #797979",
"t. c #797A79",
"y. c #7D7E7D",
"u. c #7E7E7E",
"i. c #7E7F7E",
"p. c gray50",
"a. c #808080",
"s. c gray51",
"d. c #838383",
"f. c #868786",
"g. c #888888",
"h. c gray54",
"j. c #8D8D8D",
"k. c #8D8E8D",
"l. c gray56",
"z. c #909090",
"x. c #909190",
"c. c gray57",
"v. c #939393",
"b. c gray58",
"n. c #949594",
"m. c #959595",
"M. c #969796",
"N. c #979797",
"B. c #989898",
"V. c gray60",
"C. c #9A9A9A",
"Z. c #9B9B9B",
"A. c #9D9D9D",
"S. c #9D9E9D",
"D. c gray62",
"F. c #9F9F9F",
"G. c #A0A0A0",
"H. c gray63",
"J. c gray65",
"K. c #A7A7A7",
"L. c #A9A9A9",
"P. c #AAAAAA",
"I. c #ABACAB",
"U. c #ACACAC",
"Y. c #AFAFAF",
"T. c gray69",
"R. c #B1B1B1",
"E. c #B1B2B1",
"W. c #B2B2B2",
"Q. c gray70",
"!. c #B4B4B4",
"~. c gray71",
"^. c #B7B7B7",
"/. c gray72",
"(. c #B9BAB9",
"). c gray73",
"_. c #BABBBA",
"`. c #BBBCBB",
"'. c #BCBCBC",
"]. c gray",
"[. c gray75",
"{. c #C1C1C1",
"}. c gray76",
"|. c gray77",
" X c #C5C5C5",
".X c #C6C6C6",
"XX c gray78",
"oX c #C8C8C8",
"OX c gray79",
"+X c #C9CAC9",
"@X c #CACACA",
"#X c #CBCBCB",
"$X c gray80",
"%X c #CCCDCC",
"&X c #CDCDCD",
"*X c #CDCECD",
"=X c gray81",
"-X c #CFD0CF",
";X c #D0D0D0",
":X c gray82",
">X c #D3D4D3",
",X c gray83",
"<X c #D5D5D5",
"1X c #D5D6D5",
"2X c gray84",
"3X c #D7D7D7",
"4X c #D8D8D8",
"5X c #D8D9D8",
"6X c gray85",
"7X c #DADADA",
"8X c gray86",
"9X c #DBDCDB",
"0X c #DDDDDD",
"qX c gray87",
"wX c #DFDFDF",
"eX c gray88",
"rX c #E1E1E1",
"tX c #E2E2E2",
"yX c gray89",
"uX c #E3E4E3",
"iX c #E4E4E4",
"pX c gray90",
"aX c #E6E6E6",
"sX c #E7E7E7",
"dX c gray91",
"fX c #E9E9E9",
"gX c #EAEAEA",
"hX c gray92",
"jX c gray93",
"kX c #EEEEEE",
"lX c #EFEFEF",
"zX c gray94",
"xX c #F1F1F1",
"cX c #F3F3F3",
"vX c #F4F4F4",
"bX c gray96",
"nX c #F6F6F6",
"mX c gray97",
"MX c #F8F8F8",
"NX c #F9F9F9",
"BX c gray98",
"VX c #FBFBFB",
"CX c gray99",
"ZX c #FDFDFD",
"AX c #FEFEFE",
"SX c gray100",
/* pixels */
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXgXR.a.@.E E ` l.rXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXCX!.! ; . . . . . . . 2 d.CXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXdXE . . . . . . . . . . . . $.z.@.@.7.Y.bXSXSXSXSXSXSXSXSXSXrX@X7XSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXY . . . . . . . . . . . . . . . . . . . j }.SXSXSXSXSXSX8X|.<XBXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSX<X. . . . . . . . . . . . . . . . . . . . . 3 :XSXSXSXSX<XcXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSX^.. . . . . . . . . . . . . . . . . . . . . . Q SXSXcX:XcXSXSXSXbXuX<XgXSXSXSXSXSXSXSXSXSXSXSXSXSXcXb.0XSXSXSXSXSX",
"SXSXSXSXSXSXSX@X. . . . . . . . . . . . . . . . . . . . . . $ [.P ; v ~.8X|.|.*X0XrX<XrXSXSXSXSXSXSXSXSXSXSXgXi.e . :XSXSXSXSXSX",
"SXSXSXSXSXSXSXBXB . . . . . . . . . . j . . . . . . . . . . . . . . . . }.SXSXSXSXSXSXSXSXSXSXSXSXSXSXSX8X<.3 . . . =XSXSXSXSXSX",
"SXSXSXSXSXSXSXSX<Xm . . . . . . . 9 G.XX*X7.. . . . . . . . $ . . . . . Y.SXSXSXSXSXSXSXSXSXSXSXSXSXSX .$ . . . . . =XSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXbXL.` p @ ; m w.rXrXSXSXBXl.l . . . . . V @Xs . . . $ rXSXSXSXSXSXSXSXSXSXSXSXSXSXSX8 . . . . . . =XSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXgXlXSXSX8XCXSXSXSXSXcXZ.iXiXrX0X@XSXv.$ . . ;.SXSXSXSXSXSXSXSXSXSXSXSXSXSXSX8 . . . . . . :XSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXjXrXSXSXSXSXSXQ.mXSXSXSXSX@XSXSX8XY.[.BXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX8 . . . . . . :XSXSXSXSXSX",
"SXSXSXSXSXSXSX*XZ.w.@.` W E ` @.%.l.'.lXSXSXSX@X0X@X|.|.XXY.@XSXSXSXSX0XD.2.` Q ( -.x.*XSXSXSXSX@X|.|.3 . . . . . . D.|.|.|.|.bX",
"SXSXSXSXgXw.p . . . . . . . . @ 2 . . ; $.:X:XBXP . . . $ ; -.SXSX^.P $ . . . . . . . . M H.SXSXa . . . . . . . . . . . . . . 0X",
"SXSXSX^.t . . . . . . . . . . ; $ . . . . ; >.SXP . . . . 3 @.cXo.@ . . . . . . . . . . . . ` mXa . . . . . . . . . . . . . . 8X",
"SXSX^.; . . . . . . . . . . . . . . . . . . . H.P . . . . . P V . . . . . . . . . . . . . . . ,.p . . . . . . . . . . . . . . 0X",
"SXgXa . . . . . . 3 ^ 9.i.7. .j . . . . . . . V P . . . . . . . . . w ` w.w.` 3 . . . . . . . ; $ . . . . . . . . . . . . . . 8X",
"SXw.. . . . . . P iXSXSXSXSXSXSXd.. . . . . . . V . . . . . . . ; g.bXSXSXSXSXgXE . . . . . . . 7.*X*X3 . . . . . . K.*X*X*X*XmX",
"SX[.l.,.W l 1 t gXSXSXSXSXSXSXSXCXj . . . . . . 3 . . . . . . . Q.SXSXSXSXSXSXSXjXe . . . . . . 2.SXSX3 . . . . . . *XSXSXSXSXSX",
"SXSXSXSXSXSXlXiXSXSXSXSXSXSXSXSXSXP . . . . . . . . . . . . . ^ SXSXSXSXSXSXSXSXSX| . . . . . . ] SXSX8 . . . . . . :XSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXbX:XZ. .3 . . . . . . . . . . . . . Z.SXSXSXSXSXSXSXSXSXw.. . . . . . ~ SXSX8 . . . . . . :XSXSXSXSXSX",
"SXSXSXSXSXSXSXBX*XK.p.] m ; . . . . . . . . . . . . . . . . . ^.SXSXSXSXSXSXSXSXSXl.. . . . . . ~ SXSX8 . . . . . . =XSXSXSXSXSX",
"SXSXSXSX8Xd.H ; . . . . . . . . . . . . . . . . . . . . . . . =XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSX8 . . . . . . :XSXSXSXSXSX",
"SXSXrX] $ . . . . . . . . . . . 9 ; . . . . . . $ . . . . . . >XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSX8 . . . . . . :XSXSXSXSXSX",
"SX3Xs . . . . . . . $ p E 7.H.*XbXD . . . . . . ; . . . . . . >XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSX8 . . . . . . =XSXSXSXSXSX",
"BXB . . . . . . s x.8XSXSXSXSXSXSXS . . . . . . ; . . . . . . <XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSX3 . . . . . . =XSXSXSXSXSX",
"R.. . . . . . s iXSXSXSXSXSXSXSXSXl . . . . . . ; . . . . . . <XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSXw . . . . . . }.SXSXSXSXSX",
"w.. . . . . . -.SXSXSXSXSXSXSXSXgX- . . . . . . ; . . . . . . <XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSXv . . . . . . }.SXSXSXSXSX",
"2.. . . . . . V SXSXSXSXSXSXSXBX%.. . . . . . . $ . . . . . . <XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSXv . . . . . . L.SXSXSXSXSX",
"b.. . . . . . . >.bXSXSXSXSX:X! . . . . . . . . . . . . . . . <XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSXG . . . . . . B R.$XL.7.rX",
"gX8 . . . . . . . p @.w.>.V . . . . . . . . . . . . . . . . . <XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSX .. . . . . . . . . . . ^.",
"SXZ.$ . . . . . . . . . . . . . . l . . . . . . . . . . . . . <XSXSXSXSXSXSXSXSXSXb.. . . . . . ! SXSXY.. . . . . . . . . . . b.",
"SXSXD.9 . . . . . . . . . . . 3 i.bXB . . . . . . . . . . . . <XSXSXSXSXSXSXSXSXSXb.. . . . . . ~ SXSXBX^ . . . . . . . . . . 7.",
"SXSXSX0X2.p . . . . . . $ B a.iXSXSXb.e e e e e e e e e e e e <XSXSXSXSXSXSXSXSXSXZ.e e e e e e .SXSXSXBXl.v . . . . . . . p g.",
"SXSXSXSXSXBX<XR.Z.Z.D._.uXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX<XR.Z.B.G.^.0XSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX",
"SXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSXSX"
};

17
src/in.xpm Normal file
View File

@ -0,0 +1,17 @@
/* XPM */
static char * in_xpm[] = {
"22 11 3 1",
" c None",
". c #000000",
"+ c #FFFFFF",
"......................",
".+++++++++++++++++++. ",
".++++.++.+++.++++++. ",
".++++.++..++.+++++. ",
".++++.++..++.++++. ",
".++++.++.+.+.+++. ",
".++++.++.++..++++. ",
".++++.++.++..+++++. ",
".++++.++.+++.++++++. ",
".+++++++++++++++++++. ",
"......................"};

562
src/isdn.c Normal file
View File

@ -0,0 +1,562 @@
/*
* ISDN handling functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
/* GNU headers */
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <string.h>
#include <signal.h>
#include <errno.h>
/* own header files */
#include "globals.h"
#include "isdn.h"
static char* calls_filenames[] =
{ "/var/lib/isdn/calls", "/var/log/isdn/calls", "/var/log/isdn.log" };
char* isdn_calls_filename_from_config = NULL;
/*
* locks (via lock file) and opens a (free) ttyI device
*
* output:
* isdn_device_name, isdn_lockfile_name
*
* returns isdn file descriptor on success, -1 otherwise
*/
int open_isdn_device(char **isdn_device_name, char **isdn_lockfile_name) {
int i = 0; /* try from 0 */
int found = 0; /* free file name found */
char buf[64];
int fd;
int n;
int pid;
while (i < 64 && !found) {
snprintf(buf, sizeof(buf), "%s/LCK..ttyI%d", LOCK_PATH, i);
*isdn_lockfile_name = strdup(buf);
if ((fd = open(*isdn_lockfile_name, O_RDONLY)) >= 0) { /* exists */
/* stale? -> remove (for re-use) */
n = read(fd, buf, sizeof(buf) - 1);
close(fd);
if (n > 0) {
if (n == 4) {
if (sizeof(int) == 4)
pid = *(int*) buf;
else
pid = 0;
} else {
buf[n] = 0;
sscanf(buf, "%d", &pid);
}
if (pid > 0) {
if (kill((pid_t) pid, 0) < 0 && errno == ESRCH) { /* stale */
if (!unlink(*isdn_lockfile_name))
found = 1; /* file removed */
}
}
}
} else {
if (errno == ENOENT)
found = 1; /* file doesn't exist */
}
if (!found) i++;
}
if (found && i < 64) { /* got a valid lock file name */
/* lock device */
if ((fd = open(*isdn_lockfile_name, O_WRONLY | O_CREAT, 0666)) < 0) {
return -1;
}
snprintf(buf, sizeof(buf), "%10ld\n", (long)getpid());
write(fd, buf, strlen(buf));
close(fd);
/* finally name and open the device itself */
snprintf(buf, sizeof(buf), "/dev/ttyI%d", i);
*isdn_device_name = strdup(buf);
/* tty device would possibly block on open -> O_NONBLOCK */
return open(*isdn_device_name, O_RDWR | O_NONBLOCK);
} else
return -1;
}
/*
* tries to read the given string from the specified tty (e.g. a ttyI)
* (waits for the string if not read immediately)
*
* input:
* fd tty file descriptor
* s (0-terminated) string to compare with
* timeout give up after this number of seconds
* 0: return immediately if no data available
* -1: no timeout
* got if got != NULL, store reference to result there
*
* output:
* got pointer to string containing buffer actually read if called
* with got != NULL
* -> will be NULL on error
* NOTE: caller is responsible to free the referenced buffer
*
* returns 0 on success, -1 otherwise
*
* NOTE: currently uses a fixed size buffer, implying a maximum number
* of bytes read
*/
int tty_read(int fd, char *s, int timeout, char **got) {
int failed = 0; /* 0 or 1*/
int buf_last = 0; /* index of end of string ('\0') */
char buf[256] = "";
struct timeval tv, *tvp;
fd_set fds;
if (timeout >= 0) {
tv.tv_sec = timeout;
tv.tv_usec = 0;
tvp = &tv;
} else
tvp = NULL;
while (!strstr(buf, s) && !failed) {
FD_ZERO(&fds);
FD_SET(fd, &fds);
if (buf_last == sizeof(buf) - 1) /* buffer full */
failed = 1;
else {
if (select(FD_SETSIZE, &fds, 0, 0, tvp) == 1) { /* input ready */
read(fd, &buf[buf_last], 1); /* read 1 more byte */
buf[++buf_last] = 0;
} else { /* timeout or signal */
failed = 1;
}
}
}
/* printf("%s\n", buf); */
if (got != NULL) {
*got = strdup(buf);
}
return -failed;
}
/*
* writes specified 0-terminated string to the specified tty
*
* returns 0 on success, -1 otherwise
*/
int tty_write(int fd, char *s) {
if (write(fd, s, strlen(s)) != (int)strlen(s)) {
return -1;
}
return 0;
}
/*
* clears input and output queue of specified tty
*
* returns 0 on success, -1 otherwise
*/
int tty_clear(int fd) {
return tcflush(fd, TCIOFLUSH);
}
/*
* ISDN initialization
*
* returns 0 on success, -1 otherwise
*/
int init_isdn_device(int isdn_fd, struct termios *backup) {
int failed = 0;
int flags;
char *(init_commands[]) = {
"AT&F\n", "OK\r\n", /* restore factory settings */
"ATE0\n", "OK\r\n", /* echo off */
/*"AT&B128\n", "OK\r\n",*/ /* set outgoing packet size */
"ATI\n", "Linux ISDN\r\nOK\r\n", /* check for real isdn device */
"AT+FCLASS=8\n", "OK\r\n", /* enable audio mode */
"AT+VSM=6\n", "OK\r\n", /* set uLaw format */
"ATS18=1\n", "OK\r\n", /* set audio mode (dial out) */
"ATS14=4\n", "OK\r\n", /* layer-2 protocol = transparent */
"ATS13.4=1\n", "OK\r\n", /* CALLER NUMBER after first RING */
"ATS13.6=1\n", "OK\r\n", /* enable RUNG messages */
"ATS23=1\n", "OK\r\n" /* Calling Party Number (CPN) extended RING */
};
struct termios settings;
unsigned int i;
/* assume:
* ttyI speed is 64000 by default
*/
/* switch O_NONBLOCK off (turned on while opening) */
flags = fcntl(isdn_fd, F_GETFL, 0);
if (flags != -1) {
if (fcntl(isdn_fd, F_SETFL, flags & ~O_NONBLOCK) == -1) {
perror("G_GETFL");
return -1;
}
} else {
perror("F_GETFL");
return -1;
}
if (tcgetattr(isdn_fd, &settings))
return -1;
memcpy(backup, &settings, sizeof(struct termios));
settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ECHOCTL | ISIG);
settings.c_iflag &= ~(IXON | IXOFF | IXANY | IGNCR | ICRNL | INLCR );
settings.c_iflag |= IGNPAR;
settings.c_cflag |= HUPCL;
settings.c_oflag &= ~ONLCR;
settings.c_cc[VMIN] = 1;
settings.c_cc[VTIME] = 0;
if (tcsetattr(isdn_fd, TCSANOW, &settings))
return -1;
i = 0;
while (!failed && i < sizeof(init_commands) / sizeof(char*)) {
tty_clear(isdn_fd);
if (tty_write(isdn_fd, init_commands[i++]))
failed = 1;
else
if (tty_read(isdn_fd, init_commands[i++], ISDN_COMMAND_TIMEOUT, NULL))
failed = 1;
}
return -failed;
}
/*
* ISDN de-initialization, restores termios settings
*
* returns 0 on success, -1 otherwise
*/
int deinit_isdn_device(int isdn_fd, struct termios *backup) {
return tcsetattr(isdn_fd, TCSANOW, backup);
}
/*
* sets an MSN for the specified ttyI (originating MSN)
* fd is assumed to be in command mode
*
* returns 0 on success, -1 otherwise
*/
int isdn_setMSN(int isdn_fd, char *msn) {
char buf[256];
if (snprintf(buf, sizeof(buf), "AT&E%s\n", msn) >= (int)sizeof(buf)) {
fprintf(stderr, "Error: Specified MSN too long.\n");
return -1;
}
tty_clear(isdn_fd);
if (tty_write(isdn_fd, buf))
return -1;
else
if (tty_read(isdn_fd, "OK\r\n", ISDN_COMMAND_TIMEOUT, NULL))
return -1;
return 0;
}
/*
* sets MSNs for the specified ttyI (MSNs to listen on)
* fd is assumed to be in command mode
* msns: semicolon-separated list of msns
*
* returns 0 on success, -1 otherwise
*/
int isdn_setMSNs(int isdn_fd, char *msns) {
char buf[256];
if (snprintf(buf, sizeof(buf), "AT&L%s\n", msns) >= (int)sizeof(buf)) {
fprintf(stderr, "Error: Specified MSNs string too long.\n");
return -1;
}
tty_clear(isdn_fd);
if (tty_write(isdn_fd, buf))
return -1;
else
if (tty_read(isdn_fd, "OK\r\n", ISDN_COMMAND_TIMEOUT, NULL))
return -1;
return 0;
}
/*
* stops audio mode (enter command mode)
*
* input: self_hangup: we want to hang up ourselves
*
* returns 0 on success, -1 otherwise
*/
int isdn_stop_audio(int isdn_fd, int self_hangup) {
int result = 0;
unsigned char abort_sending[] = {DLE, DC4, 0};
unsigned char end_of_audio[] = {DLE, ETX, 0};
char *got;
tty_clear(isdn_fd);
if (self_hangup) { /* we want to hang up ourselves */
if (tty_write(isdn_fd, end_of_audio)) { /* ETX - end of audio */
fprintf(stderr, "Error sending ETX (End of audio).\n");
return -1;
}
if (tty_write(isdn_fd, abort_sending)) {/* abort sending (request) (DC4) */
fprintf(stderr, "Error sending DC4 (abort sending).\n");
return -1;
}
if (tty_read(isdn_fd, end_of_audio, ISDN_COMMAND_TIMEOUT, NULL)) {
fprintf(stderr, "Error waiting for ETX (End of audio).\n");
return -1;
}
if (tty_read(isdn_fd, "\r\n", ISDN_COMMAND_TIMEOUT, NULL)) {
fprintf(stderr, "Error getting line break.\n");
return -1;
}
if (tty_read(isdn_fd, "\r\n", ISDN_COMMAND_TIMEOUT, &got)) {
fprintf(stderr, "Error getting new line.\n");
}
if (!strstr(got, "VCON")) {
fprintf(stderr, "Error getting status.\n");
result = -1;
}
free(got);
} else { /* remote side hangup */
if (tty_write(isdn_fd, end_of_audio)) { /* ETX - end of audio */
fprintf(stderr, "Error sending ETX (End of audio).\n");
return -1;
}
/* there doesn't seem to come anything after remote hangup ... (?) */
}
tty_clear(isdn_fd);
return result;
}
/*
* hang up isdn device
*
* NOTE: assumes command mode
*
* returns 0 on success, -1 otherwise
*/
int isdn_hangup(int isdn_fd) {
tty_clear(isdn_fd);
if (tty_write(isdn_fd, "ATH\n"))
return -1;
if (tty_read(isdn_fd, "OK\r\n", ISDN_COMMAND_TIMEOUT, NULL))
return -1;
tty_clear(isdn_fd);
return 0;
}
/*
* Set isdn device to block mode, assuming in audio mode
*
* in blockmode, the minimum number of bytes possible to read from specified
* ttyI will be set to DEFAULT_ISDNBUF_SIZE and non blocking reads and writes
* will be enabled
*
* input:
* isdn_fd file descriptor
* flag 0 == off, 1 == on
*
* returns 0 on success, -1 otherwise
*/
int isdn_blockmode(int isdn_fd, int flag) {
struct termios settings;
int min, time;
int flags;
flags = fcntl(isdn_fd, F_GETFL, 0);
if (flags == -1) {
perror("F_GETFL");
return -1;
}
if (flag) {
min = DEFAULT_ISDNBUF_SIZE;
time = 0; /* 10 == 1sec */
flags |= O_NONBLOCK; /* select consumes much cpu time with this */
} else {
min = 1;
time = 0;
flags &= ~O_NONBLOCK;
}
if (fcntl(isdn_fd, F_SETFL, flags) == -1) {
perror("G_GETFL");
return -1;
}
if (tcgetattr(isdn_fd, &settings)) {
perror("isdn_blockmode, tcgetattr");
return -1;
}
settings.c_cc[VMIN] = min;
settings.c_cc[VTIME] = time;
if (tcsetattr(isdn_fd, TCSANOW, &settings)) {
perror("isdn_blockmode, tcsetattr");
return -1;
}
/* verify */
if (tcgetattr(isdn_fd, &settings))
return -1;
if (settings.c_cc[VMIN] != min) {
fprintf(stderr,"Error setting block size. New block size: %d.\n",
settings.c_cc[VMIN]);
return -1;
}
return 0;
}
/*
* closes ttyI device and removes lock file
*
* returns 0 on success, -1 otherwise
*/
int close_isdn_device(int isdn_fd, char *isdn_device_name,
char *isdn_lockfile_name) {
if (close(isdn_fd)) {
return -1;
}
if (unlink(isdn_lockfile_name)) {
fprintf(stderr, "Removing isdn device lock file: unlink error.\n");
return -1;
}
free(isdn_lockfile_name);
free(isdn_device_name);
return 0;
}
/*
* dials specified number (voice call)
* (proper ttyI init is assumed)
*
* returns:
* 0 on success (VCON)
* 1 on busy
* -1 otherwise (error / timeout)
*/
int isdn_dial(int isdn_fd, char *number, int timeout) {
char *s;
int result;
char *got;
if ((s = (char*) malloc(strlen(number) + 5))) {
snprintf(s, strlen(number) + 5, "ATD%s\n", number);
tty_clear(isdn_fd);
result = tty_write(isdn_fd, s);
free(s);
if (result) {
fprintf(stderr, "Error dialing.\n");
return -1;
}
}
if (tty_read(isdn_fd, "\r\n", timeout, NULL)) /* error / timeout */
return -1;
if (tty_read(isdn_fd, "\r\n", ISDN_COMMAND_TIMEOUT, &got))
return -1;
if (strstr(got, "BUSY\r\n")) {
free(got);
return 1;
}
if (strstr(got, "VCON\r\n")) {
free(got);
return 0;
}
free(got);
return -1; /* failed somehow */
}
/*
* sets ttyI to full duplex mode
* (should be called directly after VCON)
*
* returns 0 on success, -1 otherwise
*/
int isdn_set_full_duplex(int isdn_fd) {
tty_clear(isdn_fd);
if (tty_write(isdn_fd, "AT+VRX+VTX\n"))
return -1;
return 0;
}
/*
* returns the name of the calls file (originally just /var/lib/isdn/calls)
* on error, returns NULL
*/
char* isdn_get_calls_filename(void) {
unsigned int i;
int fd;
if (isdn_calls_filename_from_config &&
(fd = open(isdn_calls_filename_from_config, O_RDONLY)) != -1)
{
close(fd);
if (debug)
fprintf(stderr,
"Using calls file listed in I4L config.\n");
return isdn_calls_filename_from_config;
}
for (i = 0; i < sizeof(calls_filenames) / sizeof(char*); i++) {
if ((fd = open(calls_filenames[i], O_RDONLY)) != -1) {
close(fd);
return calls_filenames[i];
}
}
return NULL;
}

67
src/isdn.h Normal file
View File

@ -0,0 +1,67 @@
/*
* ISDN handling functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#define LOCK_PATH "/var/lock"
#define DEFAULT_ISDNBUF_SIZE 255
#define ISDN_COMMAND_TIMEOUT 1
/* 0 (master MSN) or MSN to use as identification on outgoing calls */
#define DEFAULT_MSN "0"
/* "*" (wildcard) or comma-separated list of MSNs */
#define DEFAULT_MSNS "*"
#define ISDN_SPEED 8000
#define ETX 0x03
#define DC4 0x14
#define DLE 0x10
#define ISDN_CONFIG_FILENAME "/etc/isdn/isdn.conf"
extern char* isdn_calls_filename_from_config;
int open_isdn_device(char **isdn_device_name, char **isdn_lockfile_name);
int init_isdn_device(int isdn_fd, struct termios *backup);
int deinit_isdn_device(int isdn_fd, struct termios *backup);
int isdn_setMSN(int isdn_fd, char *msn);
int isdn_setMSNs(int isdn_fd, char *msns);
int isdn_stop_audio(int isdn_fd, int self_hangup);
int isdn_hangup(int isdn_fd);
int isdn_blockmode(int isdn_fd, int flag);
int close_isdn_device(int isdn_fd, char *isdn_device_name,
char *isdn_lockfile_name);
int isdn_dial(int isdn_fd, char *number, int timeout);
int isdn_set_full_duplex(int isdn_fd);
int tty_read(int fd, char *s, int timeout, char **got);
int tty_write(int fd, char *s);
int tty_clear(int fd);
char* isdn_get_calls_filename(void);

25
src/isdnlexer.h Normal file
View File

@ -0,0 +1,25 @@
/*
* isdn4linux options file format additional lexer declarations
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
void isdn_lexer_init(char* filename);
void isdn_lexer_deinit();

281
src/isdnlexer.l Normal file
View File

@ -0,0 +1,281 @@
%option prefix="isdn_"
%option nounput
%{
/*
* isdn4linux options file format lexer
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#define YYSTYPE char*
/* GNU headers */
#include <string.h>
#include <libgen.h>
/* own headers */
#include "globals.h"
#include "isdnparser.h"
#include "isdnlexer.h"
typedef struct isdn_include_t isdn_include_t;
struct isdn_include_t {
char* filename;
YYLTYPE location;
YY_BUFFER_STATE state;
isdn_include_t* next;
};
isdn_include_t* isdn_include_list;
char* isdn_filename;
YYLTYPE isdn_lloc;
void isdn_locate();
%}
LETTER [a-zA-Z]
DIGIT [0-9]
STRING ([^ {}"\n]|\\\n)+
/* exclusive start condition for C-style comments */
%x _INCLUDE_
%x _VALUE_
%%
INCLUDE([ \t]|"\\\n")*"(" {
isdn_locate();
BEGIN(_INCLUDE_);
}
<_INCLUDE_>[^ \t)]+ { /* got absolute or relative (to the current
* file) filename
*/
isdn_include_t* temp = (isdn_include_t*)
malloc(sizeof(isdn_include_t));
isdn_include_t* i; /* iterator */
int loop_detected;
FILE* temp_in;
isdn_locate();
temp->filename = isdn_filename;
temp->location = isdn_lloc;
temp->state = YY_CURRENT_BUFFER;
temp->next = isdn_include_list;
isdn_include_list = temp;
if (isdn_text[0] == '/') { /* absolute path */
isdn_filename = strdup(isdn_text);
} else { /* relative path */
char* path1 = strdup(isdn_filename); /* old
name */
char* path2 = dirname(path1); /* just dir */
asprintf(&isdn_filename, "%s/%s",
path2, isdn_text);
free(path1);
}
/* loop detection */
loop_detected = 0;
for (i = isdn_include_list;
i != NULL && !loop_detected;
i = i->next)
{
if (!strcmp(i->filename, isdn_filename))
loop_detected = 1;
}
if (loop_detected ||
!(temp_in = fopen(isdn_filename, "r")))
{
/* ignoring non-existent included file */
if (debug) {
if (loop_detected)
fprintf(stderr, "Loop detected ");
else
fprintf(stderr, "Error ");
fprintf(stderr,
"reading ISDN options file %s "
"from %s. Ignoring.\n",
isdn_filename, temp->filename);
}
/* recover to old buffer */
free(isdn_filename);
isdn_filename = temp->filename;
isdn_include_list = temp->next;
free(temp);
} else {
/* include file OK */
isdn_in = temp_in;
if (debug)
fprintf(stderr,
"Reading options file %s "
"from %s ...\n",
isdn_filename, temp->filename);
yy_switch_to_buffer(
yy_create_buffer(isdn_in, YY_BUF_SIZE));
BEGIN(INITIAL);
isdn_lloc.first_line = 1;
isdn_lloc.last_line = 1;
isdn_lloc.first_column = 1;
isdn_lloc.last_column = 1;
}
}
<<EOF>> { /* end of current file */
if (!isdn_include_list) { /* last buffer */
yyterminate();
} else { /* restore previous buffer */
isdn_include_t* temp = isdn_include_list;
if (debug)
fprintf(stderr, "Returning to %s ...\n",
temp->filename);
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(temp->state);
BEGIN(_INCLUDE_);
isdn_lloc = temp->location;
free(isdn_filename);
isdn_filename = temp->filename;
isdn_include_list = temp->next;
free(temp);
}
}
<_INCLUDE_>[ \t]+ { /* eat whitespace in _INCLUDE_ mode */
isdn_locate();
}
<_INCLUDE_>")" { /* return to normal mode */
isdn_locate();
BEGIN(INITIAL);
}
{LETTER}+({DIGIT}|{LETTER})* { /* NAME */
isdn_locate();
isdn_lval = strdup(isdn_text);
return ISDN_TOKEN_NAME;
}
<_VALUE_>([ \t]|"\\\n")+ { /* whitespace */
isdn_locate();
}
<_VALUE_>"{" { /* subsection begin */
isdn_locate();
BEGIN(INITIAL);
return *isdn_text;
}
<_VALUE_>(""|{STRING}(([ \t]|"\\\n")+{STRING})*)\n { /* VALUE */
isdn_locate();
isdn_lval = strdup(isdn_text);
isdn_lval = realloc(isdn_lval,
strlen(isdn_text));
isdn_lval[strlen(isdn_text) - 1] = '\0';
BEGIN(INITIAL);
return ISDN_TOKEN_VALUE;
}
<_VALUE_>\"[^"]*\"([ \t]|"\\\n")*\n { /* quoted VALUE */
int len = strchr(isdn_text + 1, '"') - isdn_text;
isdn_locate();
isdn_lval = (char *)malloc(len);
strncpy(isdn_lval, isdn_text + 1, len - 1);
isdn_lval[len - 1] = '\0';
BEGIN(INITIAL);
return ISDN_TOKEN_VALUE;
}
"#".* { /* eat up comments */
isdn_locate();
}
"=" {
isdn_locate();
BEGIN(_VALUE_);
return *isdn_text;
}
([ \t]|"\\\n")+ { /* eat up whitespace */
isdn_locate();
}
("}"|"["|"]") { /* subsection end or NAME bracket */
isdn_locate();
return *isdn_text;
}
\n { /* real new line */
isdn_locate();
}
. { /* eat up rest */
isdn_locate();
if (debug) {
fprintf(stderr,
"isdnlexer: Unrecognized character: %c "
"at %d:%d\n",
*isdn_text,
isdn_lloc.first_line,
isdn_lloc.first_column);
}
}
%%
/* For portability's sake */
int isdn_wrap() { return 1; }
/*
* adjusts isdn_lloc according to isdn_text
*/
void isdn_locate() {
char* temp;
isdn_lloc.first_line = isdn_lloc.last_line;
isdn_lloc.first_column = isdn_lloc.last_column;
for (temp = yytext; *temp != '\0'; temp++) {
if (*temp == '\n') {
++ isdn_lloc.last_line;
isdn_lloc.last_column = 1;
} else {
++ isdn_lloc.last_column;
}
}
}
/*
* to be called directly before the parser run
*
* on success, isdn_in contains valid FILE* handle, else NULL
*/
void isdn_lexer_init(char* filename) {
isdn_lloc.first_line = 1;
isdn_lloc.first_column = 1;
isdn_lloc.last_line = 1;
isdn_lloc.last_column = 1;
isdn_include_list = NULL;
if (debug)
fprintf(stderr, "Reading options file: %s ...\n", filename);
if (!(isdn_in = fopen(filename, "r"))) {
fprintf(stderr, "Error opening options file %s.\n", filename);
} else {
isdn_filename = strdup(filename);
}
}
/*
* to be called directly after the parser run
*/
void isdn_lexer_deinit() {
if (fclose(isdn_in) == EOF) {
fprintf(stderr, "Warning: Couldn't close options file.\n");
}
free(isdn_filename);
}

178
src/isdnparser.y Normal file
View File

@ -0,0 +1,178 @@
%name-prefix="isdn_"
%{
/*
* isdn4linux options file format parser
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* regular GNU system includes */
#include <stdio.h>
#include <stdlib.h>
/* own header files */
#include "globals.h"
#include "util.h"
#include "settings.h"
#include "isdntree.h"
typedef struct isdn_list_store_t isdn_list_store_t;
struct isdn_list_store_t {
isdn_tree_node_t* list; /* list itself (start) */
isdn_tree_node_t** last; /* pointer to pointer to last element */
/* (which in turn should always be NULL) */
};
int isdn_lex(void);
void isdn_error(const char *message);
%}
/* types of semantic values */
%union {
char* s;
isdn_list_store_t list;
isdn_tree_node_t* element;
}
/* terminal symbols */
%token <s> ISDN_TOKEN_NAME
%token <s> ISDN_TOKEN_VALUE
/* non terminal symbols */
%type <list> config;
%type <list> sections;
%type <element> section;
%type <list> entries;
%type <element> entry;
%type <s> value;
%%
config : entries sections
{
if ($1.list == NULL) {
$$ = $2;
} else {
$$.list = $1.list;
*$1.last = $2.list;
$$.last = $2.last;
}
isdn_tree = $$.list;
}
;
sections : { $$.list = NULL; $$.last = NULL; }
| sections section
{
if ($1.list == NULL) {
$$.list = $2;
$$.last = &$2->next;
} else {
$$.list = $1.list;
*$1.last = $2;
$$.last = &$2->next;
}
}
;
section : '[' ISDN_TOKEN_NAME ']' entries
{
if (!($$ =
(isdn_tree_node_t*) malloc(sizeof(isdn_tree_node_t))))
{
fprintf(stderr, "Error: Out of memory.\n");
exit(1);
}
$$->type = ISDN_NODE_TYPE_SECTION;
$$->name = $2;
$$->content.section = $4.list;
/* finally: only list needed */
$$->next = NULL;
}
;
entries : { $$.list = NULL; $$.last = NULL; }
| entries entry
{
if ($1.list == NULL) {
$$.list = $2;
$$.last = &$2->next;
} else {
$$.list = $1.list;
*$1.last = $2;
$$.last = &$2->next;
}
}
| entries error
{
fprintf(stderr, "Error region from %d:%d up to %d:%d.\n",
@2.first_line, @2.first_column,
@2.last_line, @2.last_column);
$$ = $1;
}
;
entry : ISDN_TOKEN_NAME '=' value
{
if (!($$ =
(isdn_tree_node_t*) malloc(sizeof(isdn_tree_node_t))))
{
fprintf(stderr, "Error: Out of memory.\n");
exit(1);
}
$$->type = ISDN_NODE_TYPE_ENTRY;
$$->name = $1;
$$->content.value = $3;
$$->next = NULL;
}
| ISDN_TOKEN_NAME '=' '{' config '}'
{
if (!($$ =
(isdn_tree_node_t*) malloc(sizeof(isdn_tree_node_t))))
{
fprintf(stderr, "Error: Out of memory.\n");
exit(1);
}
$$->type = ISDN_NODE_TYPE_SUBSECTION;
$$->name = $1;
$$->content.subsection = $4.list;
/* finally: only list needed */
$$->next = NULL;
}
;
value : ISDN_TOKEN_VALUE
| ISDN_TOKEN_NAME
;
%%
/*
* callback for yyparse(), (also) called on errors (hopefully) handled
* by error token actions in grammar, but not if errors occur to
* often (bison needs 3 "correct" tokens to recover)
*/
void isdn_error(const char *message) {
if (debug)
fprintf(stderr,
"Warning: Parsing isdn options file: %d:%d: %s.\n",
isdn_lloc.first_line, isdn_lloc.first_column, message);
}

105
src/isdntree.c Normal file
View File

@ -0,0 +1,105 @@
/*
* isdn4linux options file tree support
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* GNU headers */
#include <stdio.h>
#include <stdlib.h>
/* own headers */
#include "isdntree.h"
isdn_tree_node_t* isdn_tree;
/*
* helper function for isdn_tree_dump recursively dumping the tree
*/
static void isdn_tree_dump_list(isdn_tree_node_t* list, int indent) {
while (list != NULL) {
switch (list->type) {
case ISDN_NODE_TYPE_ENTRY:
printf("%*sEntry \"%s\" => \"%s\"\n",
indent, "", list->name, list->content.value);
break;
case ISDN_NODE_TYPE_SECTION:
printf("%*sSection [%s]:\n",
indent, "", list->name);
isdn_tree_dump_list(list->content.section, indent + 2);
break;
case ISDN_NODE_TYPE_SUBSECTION:
printf("%*sSubsection \"%s\":\n",
indent, "", list->name);
isdn_tree_dump_list(list->content.subsection, indent + 2);
break;
default:
fprintf(stderr, "Unknown ISDN_NODE_TYPE\n");
}
list = list->next;
}
}
/*
* dump whole tree to stdout
*/
void isdn_tree_dump() {
printf("ISDN config dump:\n");
isdn_tree_dump_list(isdn_tree, 2);
}
/*
* helper for isdn_tree_free
* -> recursive release of memory from tree
*/
static void isdn_tree_free_list(isdn_tree_node_t* list) {
while (list != NULL) {
isdn_tree_node_t* temp;
free(list->name);
switch (list->type) {
case ISDN_NODE_TYPE_ENTRY:
free(list->content.value);
break;
case ISDN_NODE_TYPE_SECTION:
isdn_tree_free_list(list->content.section);
break;
case ISDN_NODE_TYPE_SUBSECTION:
isdn_tree_free_list(list->content.subsection);
break;
default:
fprintf(stderr, "Unknown ISDN_NODE_TYPE\n");
}
temp = list->next;
free(list);
list = temp;
}
}
/*
* cleans up: releases all memory associated with tree
*/
void isdn_tree_free() {
isdn_tree_free_list(isdn_tree);
}

55
src/isdntree.h Normal file
View File

@ -0,0 +1,55 @@
/*
* isdn4linux options file tree support
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _ISDNTREE_H
#define _ISDNTREE_H
typedef enum isdn_node_type_t isdn_node_type_t;
typedef union isdn_node_value_t isdn_node_value_t;
typedef struct isdn_tree_node_t isdn_tree_node_t;
enum isdn_node_type_t {
ISDN_NODE_TYPE_ENTRY,
ISDN_NODE_TYPE_SECTION,
ISDN_NODE_TYPE_SUBSECTION
};
union isdn_node_value_t {
char* value;
isdn_tree_node_t* section;
isdn_tree_node_t* subsection;
};
struct isdn_tree_node_t {
isdn_node_type_t type;
char* name;
isdn_node_value_t content;
isdn_tree_node_t* next; /* it's actually a list */
};
extern isdn_tree_node_t* isdn_tree;
void isdn_tree_dump();
void isdn_tree_free();
#endif /* _ISDNTREE_H */

468
src/llcheck.c Normal file
View File

@ -0,0 +1,468 @@
/*
* line level checker functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
/* regular GNU system includes */
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
/* GTK */
#include <gtk/gtk.h>
/* own header files */
#include "globals.h"
#include "llcheck.h"
#include "session.h"
#include "gtk.h"
/* constants */
/* number of milliseconds for history */
#define HISTORY_TIME 1500
/*
* the chain link type for the maximum history
*/
struct history_t {
double value;
struct history_t *next;
};
/*
* return an empty (all zero) history of fixed size (10)
*/
struct history_t *history_new(void) {
struct history_t *root = NULL;
struct history_t *temp;
int i;
for (i = 0; i < 10; i++) {
temp = root;
root = (struct history_t *)malloc(sizeof(struct history_t));
root->value = 0.0;
root->next = temp;
}
return root;
}
/*
* free memory allocated for history
*/
void history_free(struct history_t *history) {
while (history != NULL) {
struct history_t *next = history->next;
free(history);
history = next;
}
}
/*
* appends x to history (rotating) and returns maximum value in whole history
*
* NOTE: history is assumed to be non-empty
*/
double history_append(struct history_t **history, double x) {
double result = x;
struct history_t **hist = &(*history)->next;
/* get new maximum */
while (*hist != NULL) {
if ((*hist)->value > result)
result = (*hist)->value;
hist = &(*hist)->next;
}
/* append */
*hist = *history; /* hist is ** to last element -> append old first one */
*history = (*history)->next;
(*hist)->next = NULL;
(*hist)->value = x;
return result;
}
/*
* sets history to all zero
*/
void history_reset(struct history_t *history) {
while (history) {
history->value = 0.0;
history = history->next;
}
}
/*
* called when OK button is clicked
*/
static void llcheck_quit(GtkObject *window) {
session_t *session = gtk_object_get_data(window, "session");
GtkWidget *bar = gtk_object_get_data(window, "bar");
/* remove own and restore old handlers */
gtk_input_remove(session->gtk_audio_input_tag);
session_io_handlers_start(session);
/* stop effect */
session_effect_stop(session);
llcheck_bar_deinit(bar);
gtk_widget_destroy(GTK_WIDGET(window));
session_set_state(session, STATE_READY);
}
/*
* gdk callback on audio input
*
* input: widget: the llcheck_bar
*/
static void llcheck_handle_audio_input(gpointer widget, gint fd _U_,
GdkInputCondition condition _U_) {
session_t *session = gtk_object_get_data(widget, "session");
int i, got;
int max = 0;
unsigned char sample;
got = read(session->audio_fd_in, session->audio_inbuf,
session->fragment_size_in);
if (got != -1) {
for (i = 0; i < got;
i += session->audio_sample_size_in) {
if (session->audio_sample_size_in == 1) {
sample = session->audio_LUT_analyze[
session->audio_LUT_out[(int)(session->audio_inbuf[i])]];
} else { /* audio_sample_size == 2 */
/* multiple byte samples are used "little endian" in int
to look up in LUT (see mediation_makeLUT) */
sample = session->audio_LUT_analyze[
session->audio_LUT_out[(int)(session->audio_inbuf[i]) |
(int)(session->audio_inbuf[i+1]) << 8]];
}
if (abs((int)sample - 128) > max)
max = abs((int)sample - 128);
}
llcheck_bar_set(widget, (double)max / 128);
} else {
switch (errno) {
case EAGAIN:
fprintf(stderr,
"llcheck_handle_audio_input: "
"EAGAIN - no data immediately available.\n");
break;
case EBADF:
fprintf(stderr,
"llcheck_handle_audio_input: "
"EBADF - invalid file descriptor.\n");
break;
case EINTR:
fprintf(stderr,
"llcheck_handle_audio_input: EINTR - interrupted by signal.\n");
break;
case EIO:
fprintf(stderr,
"llcheck_handle_audio_input: EIO - hardware error.\n");
break;
}
}
}
/*
* called when sound is requested in level check window
*
* input: widget: (play) button
* data: session pointer
*/
static void llcheck_play(GtkWidget *widget, gpointer data) {
session_t *session = (session_t *)data;
GtkWidget *bar = gtk_object_get_data(GTK_OBJECT(widget), "bar");
if (session->effect != EFFECT_NONE) { /* already playing -> stop feeding */
gtk_input_remove(session->effect_tag);
}
/* carefully reset audio */
gtk_input_remove(session->gtk_audio_input_tag);
session_reset_audio(session);
session->gtk_audio_input_tag = gtk_input_add_full(session->audio_fd_in,
GDK_INPUT_READ,
llcheck_handle_audio_input,
NULL,
(gpointer) bar,
NULL);
/* start recording (again) */
read(session->audio_fd_in, session->audio_inbuf,
session->fragment_size_in);
/* finally, start playing */
session_effect_start(session, EFFECT_TEST);
}
/*
* Returns a line level check bar
* input: width, height: size of the whole widget
* r, g, b: color of bright bar, dark bar will be some derivative
* of it
*
*/
GtkWidget *llcheck_bar_new(gint width, gint height,
unsigned char r, unsigned char g, unsigned char b) {
GtkWidget *progress_bar;
GtkWidget *bar;
GtkRcStyle *style;
GdkColor color;
/* the result to prepare */
bar = gtk_hbox_new(FALSE, 0);
gtk_widget_set_size_request(bar, width, height);
gtk_object_set_data(GTK_OBJECT(bar), "width", GINT_TO_POINTER(width));
/* progress bar: fast/slow relation progressbar */
progress_bar = gtk_progress_bar_new();
style = gtk_rc_style_new();
style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_BG;
color.red = r * 257; color.green = g * 257; color.blue = b * 257;
gdk_colormap_alloc_color(gtk_widget_get_colormap(bar), &color,
TRUE, TRUE);
style->bg[GTK_STATE_PRELIGHT] = color;
style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
color.red = r * 257 * 2 / 3;
color.green = g * 257 * 2 / 3;
color.blue = b * 257 * 2 / 3;
gdk_colormap_alloc_color(gtk_widget_get_colormap(bar), &color,
TRUE, TRUE);
style->bg[GTK_STATE_NORMAL] = color;
gtk_widget_modify_style(progress_bar, style);
gtk_rc_style_unref(style);
gtk_progress_set_percentage(GTK_PROGRESS(progress_bar), 0.0); /* 0..1 */
gtk_object_set_data(GTK_OBJECT(bar), "pbar1", (gpointer) progress_bar);
gtk_widget_set_size_request(progress_bar, 1, -1); /* 1..width-1 */
gtk_box_pack_start(GTK_BOX(bar), progress_bar, TRUE, TRUE, 0);
gtk_widget_show(progress_bar);
/* progress bar: rest */
progress_bar = gtk_progress_bar_new();
style = gtk_rc_style_new();
style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
color.red = r * 257 / 3;
color.green = g * 257 / 3;
color.blue = b * 257 / 3;
gdk_colormap_alloc_color(gtk_widget_get_colormap(bar), &color,
TRUE, TRUE);
style->bg[GTK_STATE_NORMAL] = color;
gtk_widget_modify_style(progress_bar, style);
gtk_rc_style_unref(style);
gtk_progress_set_percentage(GTK_PROGRESS(progress_bar), 0.0);
gtk_widget_set_size_request(progress_bar, width - 1, -1); /* 1..width-1 */
gtk_object_set_data(GTK_OBJECT(bar), "pbar2", (gpointer) progress_bar);
gtk_object_set_data(GTK_OBJECT(bar), "history", (gpointer) history_new());
gtk_box_pack_start(GTK_BOX(bar), progress_bar, TRUE, TRUE, 0);
gtk_widget_show(progress_bar);
return bar;
}
/*
* set state of line level check bar and update maximum history
*
* input: bar: llcheck_bar
* max: the current maximum (0.0 <= max <= 1.0)
*/
void llcheck_bar_set(GtkWidget *bar, double max) {
/* the maximum area */
GtkWidget *pbar1 =
(GtkWidget *)gtk_object_get_data(GTK_OBJECT(bar), "pbar1");
/* the dark area */
GtkWidget *pbar2 =
(GtkWidget *)gtk_object_get_data(GTK_OBJECT(bar), "pbar2");
struct history_t *history =
(struct history_t *)gtk_object_get_data(GTK_OBJECT(bar), "history");
double maxmax = history_append(&history, max);
int width = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(bar), "width"));
/* saving additional width
(bar->allocation.width is valid only with shown widgets) */
int pbar1size;
double percentage;
gtk_object_set_data(GTK_OBJECT(bar), "history", history);
pbar1size = maxmax * (width - 2) + 1;
gtk_widget_set_size_request(pbar1, pbar1size, -1);
gtk_widget_set_size_request(pbar2, width - pbar1size, -1);
percentage = maxmax > 0.0 ? max / maxmax : 0.0;
gtk_progress_set_percentage(GTK_PROGRESS(pbar1), percentage);
}
/*
* set line level check bar to all zero (history included);
*/
void llcheck_bar_reset(GtkWidget *bar) {
struct history_t *history =
(struct history_t *)gtk_object_get_data(GTK_OBJECT(bar), "history");
history_reset(history);
llcheck_bar_set(bar, 0.0);
}
/*
* deinit bar (free history mem ...)
*/
void llcheck_bar_deinit(GtkWidget *bar) {
struct history_t *history = gtk_object_get_data(GTK_OBJECT(bar), "history");
history_free(history);
}
/*
* The Line level check callback
* -> displays dialog window with level check bar and play button
* -> modal
*/
void llcheck(GtkWidget *widget _U_, gpointer data, guint action _U_) {
session_t *session = (session_t *) data;
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *button_box;
GtkWidget *button;
GtkWidget *label;
GtkWidget *bar;
/* set to service state -> open audio device */
if (!session_set_state(session, STATE_SERVICE)) {
/* the window itself */
window = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(window), _("Line Level Check"));
gtk_object_set(GTK_OBJECT(window), "allow_shrink", FALSE, NULL);
gtk_object_set(GTK_OBJECT(window), "allow_grow", FALSE, NULL);
/* new big vbox */
vbox = gtk_vbox_new(FALSE, 10);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), vbox);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
gtk_widget_show(vbox);
/* message label */
label = gtk_label_new(_("Please check the line input level\n"
"and adjust it using your favorite\n"
"mixer application.\n"
"You can also play a sound\n"
"to test the sound output."));
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
gtk_box_pack_start(GTK_BOX(vbox), label,
FALSE, FALSE, 0);
gtk_widget_show(label);
/* the line level check bar */
bar = llcheck_bar_new(300, 20, 200, 0, 0);
gtk_box_pack_start(GTK_BOX(vbox), bar, FALSE, FALSE, 0);
gtk_widget_show(bar);
/* action area */
button_box = gtk_hbutton_box_new();
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->action_area),
button_box);
gtk_widget_show(button_box);
/* the play button */
button = gtk_button_new_with_label(_("Play sound"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(llcheck_play),
(gpointer) session );
gtk_widget_show(button);
/* save session in window (quit(): audio handling) */
gtk_object_set_data(GTK_OBJECT(window), "session", (gpointer) session);
/* save bar in window (quit(): destroy) */
gtk_object_set_data(GTK_OBJECT(window), "bar", (gpointer) bar);
/* save session in bar widget (input handling) */
gtk_object_set_data(GTK_OBJECT(bar), "session", (gpointer) session);
/* save bar in button (in case play button is pressed) */
gtk_object_set_data(GTK_OBJECT(button), "bar", (gpointer) bar);
/* the OK button */
button = gtk_button_new_with_label(_("OK"));
gtk_box_pack_start_defaults(GTK_BOX(button_box), button);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(llcheck_quit), GTK_OBJECT(window));
/* handler for kill function of window */
gtk_signal_connect_object(GTK_OBJECT(window), "delete_event",
GTK_SIGNAL_FUNC(llcheck_quit), GTK_OBJECT(window));
gtk_widget_show(button);
gtk_window_set_modal(GTK_WINDOW(window), TRUE);
/* remove old and set up own audio input handler */
session_io_handlers_stop(session);
session->gtk_audio_input_tag = gtk_input_add_full(session->audio_fd_in,
GDK_INPUT_READ,
llcheck_handle_audio_input,
NULL,
(gpointer) bar,
NULL);
read(session->audio_fd_in, session->audio_inbuf, /* start recording */
session->fragment_size_in);
/* show everything */
gtk_widget_show(window);
} else {
show_audio_error_dialog();
}
}
/* called when line levels view check button is toggled */
void llcheck_toggle_cb(GtkWidget *widget _U_, gpointer data, guint action _U_) {
session_t *session = (session_t *) data;
if (GTK_CHECK_MENU_ITEM (session->llcheck_check_menu_item)->active) {
gtk_widget_show(session->llcheck);
session->option_show_llcheck = 1;
} else {
gtk_widget_hide(session->llcheck);
session->option_show_llcheck = 0;
/* shrink if no growing callerid monitor present */
if (!session->option_show_callerid)
gtk_window_resize(GTK_WINDOW(session->main_window), 1, 1);
}
}

30
src/llcheck.h Normal file
View File

@ -0,0 +1,30 @@
/*
* line level checker functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
GtkWidget *llcheck_bar_new(gint width, gint height,
unsigned char r, unsigned char g, unsigned char b);
void llcheck_bar_set(GtkWidget *bar, double max);
void llcheck_bar_reset(GtkWidget *bar);
void llcheck_bar_deinit(GtkWidget *bar);
void llcheck(GtkWidget *widget, gpointer data, guint action);
void llcheck_toggle_cb(GtkWidget *widget, gpointer data, guint action);

466
src/mediation.c Normal file
View File

@ -0,0 +1,466 @@
/*
* functions for mediation between ISDN and OSS
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*
* NOTE:
* * for performance reasons, separate recording buffers are filled while
* mediating
*/
#include "config.h"
/* regular GNU system includes */
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <math.h>
/* own header files */
#include "globals.h"
#include "session.h"
/* ulaw conversion (LUT) */
#include "g711.h"
#include "isdn.h"
#include "sound.h"
#include "util.h"
#include "mediation.h"
#include "llcheck.h"
#include "fxgenerator.h"
#include "recording.h"
/*
* allocate memory and build look-up-tables for audio <-> isdn conversion
*
* input:
* format_in, LUT_in: used audio format and pointer to look-up-table
* for conversion of isdn -> audio
* format_out, LUT_out: the same for audio -> isdn
* LUT_generate: table for conversion of 8 bit unsigned -> isdn
* LUT_analyze: table for conversion of isdn -> 8 bit unsigned
*
* return: 0 on success, -1 otherwise
*
* NOTE: the caller has to free the memory of LUT_* itself
*/
int mediation_makeLUT(int format_in, unsigned char **LUT_in,
int format_out, unsigned char **LUT_out,
unsigned char **LUT_generate,
unsigned char **LUT_analyze,
short **LUT_ulaw2short) {
int sample_size_in;
int sample_size_out;
int buf_size_in;
int buf_size_out;
int sample;
int i;
short s;
/* Allocation */
sample_size_in = sample_size_from_format(format_in); /* isdn -> audio */
if (sample_size_in == 0 ||
!(*LUT_in = (unsigned char *)malloc(buf_size_in = sample_size_in * 256)))
return -1;
sample_size_out = sample_size_from_format(format_out); /* audio -> isdn */
if (sample_size_out == 0 ||
!(*LUT_out =
(unsigned char *)malloc(buf_size_out =
(1 + (sample_size_out - 1) * 255) * 256)))
return -1;
if (!(*LUT_generate = (unsigned char*) malloc (256)))
return -1;
if (!(*LUT_analyze = (unsigned char*) malloc (256)))
return -1;
if (!(*LUT_ulaw2short = (short*) malloc (256*sizeof(short))))
return -1;
/* Calculation */
for (i = 0; i < buf_size_in; i += sample_size_in) { /* isdn -> audio */
switch(format_in) {
case AFMT_U8:
(*LUT_in)[i] = (unsigned char)((ulaw2linear((unsigned char)i) / 256 &
0xff) ^ 0x80);
break;
case AFMT_S8:
(*LUT_in)[i] = (unsigned char)(ulaw2linear((unsigned char)i) / 256 &
0xff);
break;
case AFMT_MU_LAW:
(*LUT_in)[i] = (unsigned char)i;
break;
case AFMT_S16_LE:
sample = ulaw2linear((unsigned char)(i / 2));
(*LUT_in)[i] = (unsigned char)(sample & 0xff);
(*LUT_in)[i+1] = (unsigned char)(sample >> 8 & 0xff);
break;
case AFMT_S16_BE:
sample = ulaw2linear((unsigned char)(i / 2));
(*LUT_in)[i+1] = (unsigned char)(sample & 0xff);
(*LUT_in)[i] = (unsigned char)(sample >> 8 & 0xff);
break;
case AFMT_U16_LE:
sample = ulaw2linear((unsigned char)(i / 2));
(*LUT_in)[i] = (unsigned char)(sample & 0xff);
(*LUT_in)[i+1] = (unsigned char)((sample >> 8 & 0xff) ^ 0x80);
break;
case AFMT_U16_BE:
sample = ulaw2linear((unsigned char)(i / 2));
(*LUT_in)[i+1] = (unsigned char)(sample & 0xff);
(*LUT_in)[i] = (unsigned char)((sample >> 8 & 0xff) ^ 0x80);
break;
default:
fprintf(stderr,
"Error: "
"Unsupported format appeared while building input LUT.\n");
return -1;
}
}
for (i = 0; i < buf_size_out; i++) { /* audio -> isdn */
switch(format_out) {
case AFMT_U8:
(*LUT_out)[i] = linear2ulaw((i - 128) * 256);
break;
case AFMT_S8:
(*LUT_out)[i] = linear2ulaw(i * 256);
break;
case AFMT_MU_LAW:
(*LUT_out)[i] = (unsigned char)i;
break;
/* next 4 cases:
input int i stores first buffer byte in low byte */
case AFMT_S16_LE:
(*LUT_out)[i] = linear2ulaw((int)(signed char)(i >> 8) << 8 |
(int)(i & 0xff));
break;
case AFMT_S16_BE:
(*LUT_out)[i] = linear2ulaw((int)(signed char)(i & 0xff) << 8 |
(int)(i >> 8));
break;
case AFMT_U16_LE:
(*LUT_out)[i] = linear2ulaw(i - 32768);
break;
case AFMT_U16_BE:
(*LUT_out)[i] = linear2ulaw(((i & 0xff) << 8 | i >> 8) - 32768);
break;
default:
fprintf(stderr,
"Error: "
"Unsupported format appeared while building output LUT.\n");
return -1;
}
}
for (i = 0; i < 256; i++) { /* 8 bit unsigned -> isdn -> 8 bit unsigned */
(*LUT_generate)[i] = linear2ulaw((i - 128) * 256);
(*LUT_ulaw2short)[i] = s = ulaw2linear((unsigned char)i); /* ulaw->short */
(*LUT_analyze)[i] = (unsigned char)((s / 256 & 0xff) ^ 0x80);
}
return 0;
}
/*
* writes buffer carefully out to file (ttyI / audio device)
*
* returns 0 on success, -1 otherwise (write error)
*/
int write_buf(int fd, unsigned char *outbuf, int outbuf_size) {
int towrite = outbuf_size;
int written = 0;
/* write until everything has been written */
while (towrite && (written != -1 || errno == EAGAIN)) {
written = write(fd, &outbuf[outbuf_size - towrite], towrite);
if (debug >= 2)
fprintf(stderr, "Wrote %d bytes to device.\n", written);
if (written != -1)
towrite -= written;
else
if (errno == EAGAIN) {
if (debug)
fprintf(stderr, "write_buf: EAGAIN\n");
ant_sleep(SHORT_INTERVAL);
}
}
if (written == -1) {
perror("write_buf");
return -1;
}
return 0;
}
/* XXX: smooth samples when converting speeds in next 2 functions */
/*
* process isdn input from ttyI to sound device
*
* to be called after select found block to read in isdn file descriptor
*/
void process_isdn_source(session_t *session) {
int got, i, j;
unsigned char inbyte; /* byte read from ttyI */
int to_process; /* number of samples to process
(according to ratio / ratio_support_count) */
unsigned char sample; /* 8 bit unsigned sample */
int max = 0; /* for llcheck */
short s; /* libsndfile sample data */
got = read(session->isdn_fd, session->isdn_inbuf,
session->isdn_inbuf_size);
if (debug >= 2)
fprintf(stderr, "From isdn: got %d bytes.\n", got);
if (got != -1) {
for (i = 0; i < got; i++) {
inbyte = session->isdn_inbuf[i];
if (!session->escape == (inbyte != DLE)) {
/* normal mode or last byte was an escape in DLE mode */
/* input line level check */
sample = session->audio_LUT_analyze[inbyte];
if (abs((int)sample - 128) > max)
max = abs((int)sample - 128);
/* recording */
if (session->option_record) {
if (session->option_record_remote)
s = session->audio_LUT_ulaw2short[inbyte];
else
s = 0;
session->rec_buf_remote[session->rec_buf_remote_index++] = s;
if (session->rec_buf_remote_index >= session->rec_buf_remote_size) {
if (recording_write(session->recorder, session->rec_buf_remote,
session->rec_buf_remote_size, RECORDING_REMOTE))
fprintf(stderr, "Warning: Recording (remote) error.\n");
session->rec_buf_remote_index = 0;
}
}
/* touchtone to audio: after llcheck to monitor other end */
if (session->touchtone_countdown_audio > 0) {
inbyte = fxgenerate(session, EFFECT_TOUCHTONE,
session->touchtone_index,
(double)session->touchtone_countdown_audio /
ISDN_SPEED); /* playing reverse is ok */
session->touchtone_countdown_audio--;
}
/* mediation */
to_process = (int)floor((double)(session->samples_in + 1) *
session->ratio_in) -
(int)floor((double)session->samples_in *
session->ratio_in);
/* printf("isdn -> audio: to_process == %d\n", to_process); */
for (j = 0; j < to_process; j++) {
if (session->audio_sample_size_out == 1) {
session->audio_outbuf[session->audio_outbuf_index++] =
session->audio_LUT_in[(int)inbyte];
} else { /* audio_sample_size == 2 */
session->audio_outbuf[session->audio_outbuf_index++] =
session->audio_LUT_in[(int)inbyte * 2];
session->audio_outbuf[session->audio_outbuf_index++] =
session->audio_LUT_in[(int)inbyte * 2 + 1];
}
if (session->audio_outbuf_index >= session->fragment_size_out) {
if (write_buf(session->audio_fd_out, session->audio_outbuf,
session->fragment_size_out))
session->aborted = 1;
session->audio_outbuf_index = 0;
}
}
session->samples_in++;
if (session->escape) {
session->escape = 0;
if (debug) fprintf(stderr, "debug: escape mode off after 2x DLE.\n");
}
} else if (!session->escape && inbyte == DLE) { /* new escape: DLE */
session->escape = 1;
if (debug)
fprintf(stderr, "debug: ttyI DLE escape mode on.\n");
} else /* i.e. if (*escape) */ {
if (inbyte == DC4 || inbyte == ETX) {
session->hangup = 1;
} else {/* else: must be a touchtone: ignored */
if (debug) {
if ((inbyte >= '0' && inbyte <= '9') || inbyte == '#' ||
inbyte =='*' || (inbyte >= 'A' && inbyte <= 'D'))
fprintf(stderr, "Touchtone %c received.\n", inbyte);
else
fprintf(stderr, "Warning: Unknown escape sequence received.\n");
}
}
session->escape = 0;
if (debug) fprintf(stderr,
"debug: escape mode off after special char.\n");
}
}
llcheck_bar_set(session->llcheck_in, (double)max / 128);
} else {
fprintf(stderr, "process_isdn_source: read error (return -1).\n");
}
}
/*
* process audio input from sound device to isdn tty
*
* to be called after select found fragment(s) to read from
*/
void process_audio_source(session_t *session) {
int i, j, got, n;
unsigned char sample; /* the ulaw sample */
short s = 0; /* libsndfile sample data */
/* the ulaw sample when muted: */
unsigned char zero = session->audio_LUT_generate[128];
int to_process; /* number of samples to process
(according to ratio / ratio_support_count) */
unsigned char sampleu8; /* 8 bit unsigned sample */
int max = 0; /* for llcheck */
got = read(session->audio_fd_in, session->audio_inbuf,
session->fragment_size_in);
if (debug >= 2)
fprintf(stderr, "From audio: got %d bytes.\n", got);
if (got != -1) {
for (i = 0; i < got;
i += session->audio_sample_size_in, session->samples_out++) {
to_process = (int)floor((double)(session->samples_out + 1)
* session->ratio_out) -
(int)floor((double)session->samples_out
* session->ratio_out);
/* printf("audio -> isdn: to_process == %d\n", to_process); */
for (j = 0; j < to_process; j++) {
if (session->audio_sample_size_in == 1) {
sample = session->audio_LUT_out[(int)(session->audio_inbuf[i])];
} else { /* audio_sample_size == 2 */
/* multiple byte samples are used "little endian" in int
to look up in LUT (see mediation_makeLUT) */
sample = session->audio_LUT_out[(int)(session->audio_inbuf[i]) |
(int)(session->audio_inbuf[i+1])
<< 8];
}
/* touchtone to isdn: before llcheck to monitor it */
if (session->touchtone_countdown_isdn > 0) {
sample = fxgenerate(session, EFFECT_TOUCHTONE,
session->touchtone_index,
(double)session->touchtone_countdown_isdn /
ISDN_SPEED /* playing reverse is ok */ );
session->touchtone_countdown_isdn--;
}
if (session->option_muted) /* zero if muted */
sample = zero;
/* input line level check */
sampleu8 = session->audio_LUT_analyze[sample];
if (abs((int)sampleu8 - 128) > max)
max = abs((int)sampleu8 - 128);
/* recording */
if (session->option_record) {
if (session->option_record_local)
s = session->audio_LUT_ulaw2short[sample];
else
s = 0;
session->rec_buf_local[session->rec_buf_local_index++] = s;
if (session->rec_buf_local_index >= session->rec_buf_local_size) {
if (recording_write(session->recorder, session->rec_buf_local,
session->rec_buf_local_size, RECORDING_LOCAL))
fprintf(stderr, "Warning: Recording (local) error.\n");
session->rec_buf_local_index = 0;
}
}
n = (sample == DLE) ? 2 : 1; /* again if DLE escape */
while (n > 0) {
session->isdn_outbuf[session->isdn_outbuf_index++] = sample;
if (session->isdn_outbuf_index >= session->isdn_outbuf_size) {
/* write outbuf out */
if (write_buf(session->isdn_fd, session->isdn_outbuf,
session->isdn_outbuf_size))
session->aborted = 1;
session->isdn_outbuf_index = 0;
}
n--;
}
}
}
llcheck_bar_set(session->llcheck_out, (double)max / 128);
} else {
switch (errno) {
case EAGAIN:
if (debug)
fprintf(stderr,
"process_audio_source: "
"EAGAIN - no data immediately available (that's ok).\n");
break;
case EBADF:
fprintf(stderr,
"process_audio_source: EBADF - invalid file descriptor.\n");
break;
case EINTR:
fprintf(stderr,
"process_audio_source: EINTR - interrupted by signal.\n");
break;
case EIO:
fprintf(stderr,
"process_audio_source: EIO - hardware error.\n");
break;
}
}
}

39
src/mediation.h Normal file
View File

@ -0,0 +1,39 @@
/*
* functions for mediation between ISDN and OSS
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "session.h"
/* mediation internal recording buffer (number of shorts): */
#define MEDIATION_RECBUFSIZE 16384
extern int finished;
extern int hangup;
int mediation_makeLUT(int format_in, unsigned char **LUT_in,
int format_out, unsigned char **LUT_out,
unsigned char **LUT_generate,
unsigned char **LUT_analyze,
short **LUT_ulaw2short);
int write_buf(int fd, unsigned char *outbuf, int outbuf_size);
void process_isdn_source(session_t *session);
void process_audio_source(session_t *session);

20
src/mute.xpm Normal file
View File

@ -0,0 +1,20 @@
/* XPM */
static char * mute_xpm[] = {
"14 14 3 1",
" c None",
". c #000000",
"+ c #B70000",
" ... ",
" ..... ",
" ++ ......",
" ++ ......",
" ++ ......",
" ++...... ",
" ++.. ",
"++++++++++++ ",
"++++++++++++ ",
" ..++ ",
" ...++ ",
" .. ++ ",
" . ++ ",
". ++ "};

17
src/out.xpm Normal file
View File

@ -0,0 +1,17 @@
/* XPM */
static char * out_xpm[] = {
"22 11 3 1",
" c None",
". c #000000",
"+ c #FFFFFF",
"................. ",
".++++++++++++++++. ",
".++..++.++.+.....+. ",
".+.++.+.++.+++.++++. ",
".+.++.+.++.+++.+++++. ",
".+.++.+.++.+++.++++++.",
".+.++.+.++.+++.+++++. ",
".+.++.+.++.+++.++++. ",
".++..+++..++++.+++. ",
".++++++++++++++++. ",
"................. "};

19
src/pickup.xpm Normal file
View File

@ -0,0 +1,19 @@
/* XPM */
static char * pickup_xpm[] = {
"16 14 2 1",
" c None",
". c #20A000",
" .. ",
" .... ",
" ...... ",
" . .. . ",
" .. ",
" .. ",
" .. ",
" ",
" ",
" ............ ",
" .............. ",
"..... .....",
"..... ....",
" .. .. "};

15
src/record.xpm Normal file
View File

@ -0,0 +1,15 @@
/* XPM */
static char * record_xpm[] = {
"9 9 3 1",
" c None",
". c #FF0000",
"+ c #000000",
" .... ",
" ...... ",
"........ ",
"........+",
"........+",
"........+",
" ......++",
" ....++ ",
" ++++ "};

239
src/recording.c Normal file
View File

@ -0,0 +1,239 @@
/*
* recording functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
/* regular GNU system includes */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* sndfile audio file reading/writing library */
#include <sndfile.h>
/* own header files */
#include "globals.h"
#include "isdn.h"
#include "recording.h"
#include "util.h"
/* recorder internal buffer size (number of items, 1 item = 2 shorts): */
#define RECORDING_BUFSIZE 16384
/*
* Carefully opens a file and prepares recorder
* * when the file exists, new data will be appended
*
* File format:
*
* input:
* recorder: struct to be filled with recorder state for recording session
* until recording_close()
* filename: the base file name. It will be expanded
* with full path and extension
*
* returns: 0 on success, -1 otherwise
*/
int recording_open(struct recorder_t *recorder, char *filename,
enum recording_format_t format) {
SF_INFO sfinfo;
char *homedir;
char *fn;
/* prepare path and file */
touch_dotdir();
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return -1;
}
if (asprintf(&fn, "%s/." PACKAGE "/recordings", homedir) < 0) {
fprintf(stderr, "Warning: "
"recording_open: Couldn't allocate memory for directory name.\n");
return -1;
}
if (touch_dir(fn) < 0) {
if (debug)
fprintf(stderr,
"Warning: recording_open: Can't reach directory %s.\n", fn);
return -1;
}
free(fn);
if (asprintf(&fn, "%s/." PACKAGE "/recordings/%s.%s", homedir, filename, format & RECORDING_FORMAT_WAV ? "wav" : "aiff")
< 0) {
fprintf(stderr, "Warning: "
"recording_open: Couldn't allocate memory for directory name.\n");
return -1;
}
if (access(fn, F_OK)) { /* file doesn't exist */
sfinfo.format =
(format & RECORDING_FORMAT_WAV ? SF_FORMAT_WAV : SF_FORMAT_AIFF) |
(format & RECORDING_FORMAT_S16 ? SF_FORMAT_PCM_16 : SF_FORMAT_ULAW);
sfinfo.channels = 2;
sfinfo.samplerate = ISDN_SPEED;
if (!(recorder->sf = sf_open(fn, SFM_WRITE, &sfinfo))) {
fprintf(stderr, "recording_open: sf_open (file creation) error.\n");
return -1;
}
} else { /* file already exists */
sfinfo.format = 0;
if (!(recorder->sf = sf_open(fn, SFM_RDWR, &sfinfo))) {
fprintf(stderr, "recording_open: sf_open (reopen) error.\n");
return -1;
}
if (sf_seek(recorder->sf, 0, SEEK_END) == -1) {
fprintf(stderr, "recording_open: sf_seek error.\n");
return -1;
}
}
recorder->filename = fn;
if (!(recorder->queue =
(struct recqueue_t *) malloc (sizeof(struct recqueue_t)))) {
fprintf(stderr, "recording_open: recorder->queue malloc error.\n");
return -1;
}
if (!(recorder->queue->buf =
(short *) malloc (RECORDING_BUFSIZE * sizeof(short) * 2))) {
fprintf(stderr, "recording_open: recorder->queue->buf malloc error.\n");
return -1;
}
recorder->queue->next = NULL;
recorder->current_local = recorder->current_remote = recorder->queue;
recorder->localindex = 0;
recorder->remoteindex = 0;
return 0;
}
/*
* writes specified number of shorts to file
*
* input:
* recorder: struct with sound file state
* buf, size: the buffer of shorts with its size (number of shorts)
* channel: RECORDING_LOCAL or RECORDING_REMOTE
*
* returns: 0 on success, -1 otherwise
*/
int recording_write(struct recorder_t *recorder, short *buf, int size,
enum recording_channel_t channel) {
int i;
struct recqueue_t **link_this; /* alias for current_local or current_remote */
int *buf_index_this; /* alias for localindex or remoteindex */
struct recqueue_t *temp;
if (channel == RECORDING_LOCAL) {
link_this = &recorder->current_local;
buf_index_this = &recorder->localindex;
} else {
link_this = &recorder->current_remote;
buf_index_this = &recorder->remoteindex;
}
for (i = 0; i < size; i++) {
(*link_this)->buf[(*buf_index_this)++ * 2 + channel] = buf[i];
if (*buf_index_this >= RECORDING_BUFSIZE) { /* one buffer full */
if ((*link_this)->next == NULL) { /* expand list */
if (!((*link_this)->next =
(struct recqueue_t *) malloc (sizeof(struct recqueue_t)))) {
fprintf(stderr, "recording_write: buffer allocation error.\n");
return -1;
}
if (!((*link_this)->next->buf =
(short *) malloc (RECORDING_BUFSIZE * sizeof(short) * 2))) {
fprintf(stderr, "recording_write: buffer allocation error.\n");
return -1;
}
(*link_this)->next->next = NULL;
}
*link_this = (*link_this)->next; /* go further in list */
*buf_index_this = 0;
if (recorder->queue != recorder->current_local &&
recorder->queue != recorder->current_remote) {
/* write out buffer */
sf_writef_short(recorder->sf, recorder->queue->buf, RECORDING_BUFSIZE);
temp = recorder->queue;
recorder->queue = recorder->queue->next;
free(temp->buf);
free(temp);
}
}
}
return 0;
}
/*
* finishes recording to file, writes remaining data from queue to file
* (eventually filling a dangling channeln with silence)
*
* input:
* recorder: struct with sound file state
*
* returns: 0 on success, -1 otherwise
*/
int recording_close(struct recorder_t *recorder) {
struct recqueue_t **link_this; /* aliases for the links and their buffer - */
struct recqueue_t **link_other;
int *buf_index_this; /* indices to traverse */
int *buf_index_other;
enum recording_channel_t channel;
struct recqueue_t *temp;
/* set last, unavailable samples to zero */
if (recorder->queue == recorder->current_local) { /* traverse local samples */
link_this = &recorder->current_local;
link_other = &recorder->current_remote;
buf_index_this = &recorder->localindex;
buf_index_other = &recorder->remoteindex;
channel = RECORDING_LOCAL;
} else { /* traverse remote samples */
link_this = &recorder->current_remote;
link_other = &recorder->current_local;
buf_index_this = &recorder->remoteindex;
buf_index_other = &recorder->localindex;
channel = RECORDING_REMOTE;
}
while (*link_this != NULL) { /* traverse all chain links */
while ((*link_this != *link_other && *buf_index_this < RECORDING_BUFSIZE)
|| *buf_index_this < *buf_index_other) { /* all remaining samples */
(*link_this)->buf[(*buf_index_this)++ * 2 + channel] = 0;
}
sf_writef_short(recorder->sf, (*link_this)->buf, *buf_index_this);
*buf_index_this = 0;
temp = *link_this;
*link_this = (*link_this)->next;
free(temp->buf);
free(temp);
}
if (!sf_close(recorder->sf)) return -1;
free(recorder->filename);
return 0;
}

72
src/recording.h Normal file
View File

@ -0,0 +1,72 @@
/*
* recording functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _ANT_RECORDING_H
#define _ANT_RECORDING_H
#include "config.h"
/* regular GNU system includes */
#include <stdio.h>
/* sndfile audio file reading/writing library */
#include <sndfile.h>
enum recording_format_t {
RECORDING_FORMAT_WAV = 0x10,
RECORDING_FORMAT_AIFF = 0x20,
RECORDING_FORMAT_ULAW = 0x01,
RECORDING_FORMAT_S16 = 0x02,
RECORDING_FORMAT_MAJOR = 0xF0,
RECORDING_FORMAT_MINOR = 0x0F
};
enum recording_channel_t {
RECORDING_LOCAL = 0,
RECORDING_REMOTE = 1
};
struct recqueue_t {
struct recqueue_t *next;
short *buf;
};
struct recorder_t {
SNDFILE *sf; /* sndfile state */
char *filename; /* audio file name */
struct recqueue_t *queue; /* buffer queue for communication with libsndfile */
struct recqueue_t *current_local; /* current queue element for local input */
struct recqueue_t *current_remote;/* current queue element for remote input */
int localindex; /* indices into current block in queue */
int remoteindex;
};
int recording_open(struct recorder_t *recorder, char *filename,
enum recording_format_t format);
int recording_write(struct recorder_t *recorder, short *buf, int size,
enum recording_channel_t channel);
int recording_close(struct recorder_t *recorder);
#endif /* recording.h */

15
src/redial.xpm Normal file
View File

@ -0,0 +1,15 @@
/* XPM */
static char * redial_xpm[] = {
"14 10 2 1",
" c None",
". c #000000",
" ... ... ",
" .. ....... ",
" .. ....... ",
".. .........",
". .........",
". .........",
".. .........",
" .. ....... ",
" .. ....... ",
" ... ... "};

149
src/server.c Normal file
View File

@ -0,0 +1,149 @@
/*
* server functionality:
* * let other processes issue commands (e.g. dial)
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* regular GNU system includes */
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
/* own header files */
#include "globals.h"
#include "server.h"
#include "session.h"
#include "util.h"
/*
* returns the name of the local socket file
*
* NOTE: caller has to free himself the allocated memory
*/
char *server_local_socket_name(void) {
char *filename;
if (asprintf(&filename, "%s/." PACKAGE "/%s",
get_homedir(), SERVER_LOCAL_SOCKET_NAME) < 0) {
fprintf(stderr,
"Warning: Couldn't allocate memory for history filename.\n");
return NULL;
}
return filename;
}
/*
* init server setup for session
*/
int server_init(session_t *session) {
struct sockaddr_un local_name;
int local_sock;
size_t size;
char *filename;
filename = server_local_socket_name();
local_name.sun_family = AF_LOCAL;
strncpy(local_name.sun_path, filename, sizeof(local_name.sun_path));
size = SUN_LEN(&local_name);
free(filename);
local_sock = socket(PF_LOCAL, SOCK_STREAM, 0); /* open socket */
if (local_sock < 0) {
perror("local socket");
return -1;
}
if (touch_dotdir())
return -1;
/* bind (file) name to socket */
if (bind(local_sock, (struct sockaddr *) &local_name, size)) {
perror("local bind");
fprintf(stderr,
"This program was possibly killed by accident on last run.\n"
"In this case, try running it with option -r.\n");
return -1;
}
if (listen(local_sock, SERVER_CONNECTIONS_MAX_PENDING) < 0) {
perror("listen");
return -1;
}
session->local_sock = local_sock;
return 0;
}
/*
* callback for local input on session->local_socket
*/
void server_handle_local_input(gpointer data, gint fd _U_,
GdkInputCondition condition _U_) {
session_t *session = (session_t *) data;
int sock; /* the actual socket */
struct sockaddr_un clientname; /* data about connecting client */
socklen_t size;
char buffer[SERVER_INBUF_SIZE];
int bytes;
sock = accept(session->local_sock, (struct sockaddr *) &clientname, &size);
if (sock < 0) {
perror("local accept");
}
bytes = read(sock, buffer, SERVER_INBUF_SIZE);
if (bytes > 0) { /* got message */
if (buffer[0] == LOCAL_MSG_CALL) {
if (debug) fprintf(stderr, "Request (%d bytes): call %s.\n",
bytes, &buffer[1]);
session_make_call(session, &buffer[1]);
}
} else if (bytes < 0) { /* error */
perror("local read");
} else { /* EOF */
fprintf(stderr, "local read: EOF");
}
close(sock);
}
/*
* deinit server setup for session
*/
int server_deinit(session_t *session) {
char *filename;
close(session->local_sock);
if (-1 == unlink(filename = server_local_socket_name())) {
perror("unlink socket file");
}
free(filename);
return 0;
}

40
src/server.h Normal file
View File

@ -0,0 +1,40 @@
/*
* server functionality:
* * let other processes issue commands (dial)
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* own header files */
#include "session.h"
#define SERVER_LOCAL_SOCKET_NAME ".socket"
#define SERVER_CONNECTIONS_MAX_PENDING 5
#define SERVER_INBUF_SIZE 1024
enum local_msg_t {
LOCAL_MSG_CALL
};
char *server_local_socket_name(void);
int server_init(session_t *session);
void server_handle_local_input(gpointer data, gint fd _U_,
GdkInputCondition condition _U_);
int server_deinit(session_t *session);

1453
src/session.c Normal file

File diff suppressed because it is too large Load Diff

272
src/session.h Normal file
View File

@ -0,0 +1,272 @@
/*
* definitions for runtime session specific data handling
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _ANT_SESSION_H
#define _ANT_SESSION_H
#include "config.h"
/* regular GNU system includes */
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#include <time.h>
/* GTK */
#include <gtk/gtk.h>
/* own header files */
#include "recording.h"
#define SESSION_PRESET_SIZE 4
enum state_t {
STATE_READY, /* completely idle */
STATE_RINGING, /* somebody's calling */
STATE_RINGING_QUIET, /* same as above, audio off (device blocked) */
STATE_DIALING, /* we are dialing out */
STATE_CONVERSATION, /* we are talking */
STATE_SERVICE, /* special mode (llcheck) */
STATE_PLAYBACK, /* sound playback, usually recorded conversation */
STATE_NUMBER /* dummy to calculate size */
};
enum effect_t {
EFFECT_NONE, /* nothing is played currently */
EFFECT_RING, /* somebody's calling */
EFFECT_RINGING, /* waiting for the other end to pick up the phone */
EFFECT_TEST, /* play test sound (e.g. line level check) */
EFFECT_TOUCHTONE,/* play a touchtone */
EFFECT_SOUNDFILE /* play sound from file */
};
/*
* Data needed for setting the session state (the state is the index)
*/
struct state_data_t {
char *status_bar;
char *pick_up_label;
int pick_up_state;
char *hang_up_label;
int hang_up_state;
};
struct state_data_t state_data[STATE_NUMBER];
/*
* session data
*/
typedef struct {
/* audio device data */
char *audio_device_name_in; /* allocated memory! */
char *audio_device_name_out; /* allocated memory! */
int audio_fd_in; /* audio device file descriptors */
int audio_fd_out;
unsigned int audio_speed_in; /* sound device recording speed */
unsigned int audio_speed_out; /* sound device playback speed */
int fragment_size_in; /* sound device buffer fragment sizes in bytes */
int fragment_size_out;
int *format_priorities; /* 0-terminated sorted list of preferenced formats */
int audio_format_in; /* the actual formats */
int audio_format_out;
int audio_sample_size_in; /* number of bytes of a sample */
int audio_sample_size_out;
unsigned char *audio_inbuf; /* buffer: should have size fragment_size_in */
unsigned char *audio_outbuf; /* buffer: should have size fragment_size_out */
int audio_outbuf_index; /* needed for conversation mode output memory */
/* isdn data */
char* isdn_device_name; /* "/dev/ttyIxx", xx == 0 .. 63 */
int isdn_fd;
char* isdn_lockfile_name;
int isdn_inbuf_size;
int isdn_outbuf_size;
unsigned char *isdn_inbuf; /* 8 bit ulaw */
unsigned char *isdn_outbuf;
int isdn_inbuf_len; /* index of '\0' in audio_inbuf in command mode,
if char at this index != 0 -> reading line */
int isdn_outbuf_index; /* needed for conversation mode output memory */
int escape; /* escape mode/state RECEIVING isdn data */
int no_input; /* after this many select calls without isdn input
get back from blockmode */
struct termios isdn_backup; /* saved state to restore on exit */
char *from; /* caller's number */
char *to; /* callee's number */
/* mediation data */
/* Look-up-tables for audio <-> isdn conversion: */
unsigned char *audio_LUT_in; /* isdn -> audio */
unsigned char *audio_LUT_out; /* audio -> isdn */
unsigned char *audio_LUT_generate; /* 8 bit unsigned -> isdn */
unsigned char *audio_LUT_analyze; /* isdn -> 8 bit unsigned */
short *audio_LUT_ulaw2short; /* unsigned char (ulaw) -> short */
double ratio_in; /* ratio: audio output rate / isdn input rate */
double ratio_out; /* ratio: isdn output rate / audio input rate */
unsigned int samples_in; /* ring counter of samples: from isdn */
unsigned int samples_out; /* ... ... : from sound device */
/* recording data */
short *rec_buf_local; /* pointers to recording buffers */
short *rec_buf_remote;
int rec_buf_local_index; /* number of shorts in local recording buffer */
int rec_buf_remote_index; /* number of shorts in local recording buffer */
int rec_buf_local_size; /* recording buffer sizes */
int rec_buf_remote_size;
struct recorder_t *recorder; /* recorder internal data */
/* GUI elements in this session (GTK specific) */
GtkWidget *main_window; /* the main window (with style ...) */
GtkWidget *pick_up_button; /* the pick up button to enable / disable */
GtkWidget *pick_up_label; /* the label on the pick up button */
GtkWidget *hang_up_button; /* the hang up button to enable / disable */
GtkWidget *hang_up_label; /* the label on the hang up button */
GtkWidget *dial_number_box; /* the dial number combo box */
GList *dial_number_history; /* the last called numbers */
unsigned int dial_number_history_maxlen; /* how many numbers to remember */
unsigned int dial_number_history_pointer; /* which one to use next if req */
GtkWidget *status_bar; /* the status bar */
gint phone_context_id; /* a context for the status bar */
GtkWidget *audio_warning; /* inside status bar */
gint audio_context_id; /* a context for audio_warning */
GtkWidget *llcheck; /* line level check widget inside status bar */
GtkWidget *llcheck_in; /* input level meter */
GtkWidget *llcheck_out; /* output level meter */
GtkWidget *llcheck_check_menu_item; /* state of line levels (status bar) */
guint gtk_isdn_input_tag; /* these tags are saved to later remove handlers */
guint gtk_audio_input_tag;
GtkWidget *controlpad; /* key pad etc. */
GtkWidget *controlpad_check_menu_item; /* display state of control pad */
GtkWidget *mute_button; /* toggle button */
GtkWidget *muted_warning; /* show in status bar if muted */
gint muted_context_id; /* a context for the status bar */
GtkWidget *record_checkbutton; /* recording checkbutton */
GtkWidget *record_checkbutton_local; /* local recording checkbutton */
GtkWidget *record_checkbutton_remote; /* remote recording checkbutton */
/* caller id related */
GtkWidget *cid; /* the caller id widget itself (to show/hide) */
GtkWidget *cid_check_menu_item; /* to handle state of cid monitor (show?) */
GtkWidget *cid_list; /* the list to hold the individual call data */
GtkWidget *cid_scrolled_window; /* the home of the clist with adjustments */
gint cid_num; /* number of rows in list */
gint cid_num_max; /* maximum number of rows in list */
time_t vcon_time; /* the start of conversation mode (for duration calc.) */
time_t ring_time; /* the first sign of the conversation (dial/ring) */
/* the symbols for the CList */
GdkPixmap *symbol_in_pixmap;
GdkBitmap *symbol_in_bitmap;
GdkPixmap *symbol_out_pixmap;
GdkBitmap *symbol_out_bitmap;
GdkPixmap *symbol_record_pixmap;
GdkBitmap *symbol_record_bitmap;
GtkWidget *menuitem_settings; /* Menu items to select / deselect */
GtkWidget *menuitem_line_check;
/* ringing etc. */
guint effect_tag; /* remove this callback after e.g. ringing */
enum effect_t effect; /* which effect is currently been played? */
unsigned int effect_pos; /* sample position in effect */
char* effect_filename; /* the file to playback */
SNDFILE* effect_sndfile; /* the handle */
SF_INFO effect_sfinfo; /* info struct about effect_sndfile */
short* effect_sndfile_buffer;/*temporary buffer to construct playback output*/
int effect_sndfile_buffer_frames;/*number of frames of effect_sndfile_buffer*/
time_t effect_playback_start_time; /* start time of playback */
int touchtone_countdown_isdn; /* number of samples yet to play */
int touchtone_countdown_audio;
int touchtone_index; /* which touchtone */
/* phone specific */
enum state_t state; /* which state we are currently in */
int hangup; /* remote hangup */
int aborted; /* i/o error (isdn or audio) */
char* msn; /* originating msn, allocated memory! */
char* msns; /* comma-separated list of msns to listen on, allocated memory!*/
int unanswered; /* unanswered calls for this session */
/* some options (useful for options file handling) */
int option_save_options; /* save options on exit */
int option_release_devices; /* close sound devices while not needed */
int option_show_llcheck; /* show line level checks in main window */
int option_show_callerid; /* show callerid part in main window */
int option_show_controlpad; /* show control pad (key pad etc.) */
int option_muted; /* mute microphone (other party gets zeros) */
int option_record; /* record to file */
int option_record_local; /* record local channel */
int option_record_remote; /* record remote channel */
enum recording_format_t option_recording_format; /* recording file format */
int option_calls_merge; /* merge isdnlog */
int option_calls_merge_max_days;
char *exec_on_incoming; /* string with command to execute on incoming call */
int option_popup; /* push main window to foreground on incoming call */
char* preset_names[SESSION_PRESET_SIZE]; /* names and numbers for */
char* preset_numbers[SESSION_PRESET_SIZE]; /* preset buttons */
int local_sock; /* unix domain socket for local server functionality */
guint gtk_local_input_tag; /* gtk tag for gtk main loop select */
} session_t;
extern session_t session;
int session_set_state(session_t *session, enum state_t state);
void session_io_handlers_start(session_t *session);
void session_io_handlers_stop(session_t *session);
int session_reset_audio(session_t *session);
int session_audio_open(session_t *session);
int session_audio_close(session_t *session);
int session_audio_init(session_t *session);
int session_audio_deinit(session_t *session);
int session_init(session_t *session,
char *audio_device_name_in,
char *audio_device_name_out,
char *msn, char *msns);
void session_audio_free(session_t *session);
int session_deinit(session_t *session);
void session_effect_start(session_t *session, enum effect_t kind);
void session_effect_stop(session_t *session);
void gtk_handle_isdn_input(gpointer data, gint fd,
GdkInputCondition condition);
void gtk_handle_audio_input(gpointer data, gint fd,
GdkInputCondition condition);
void session_make_call(session_t *session, char *number);
void gtk_handle_pick_up_button(GtkWidget *widget, gpointer data);
void gtk_handle_hang_up_button(GtkWidget *widget, gpointer data);
void session_history_add(session_t *session, const char *number);
void session_history_append(session_t *session, char *number);
#endif /* session.h */

601
src/settings.c Normal file
View File

@ -0,0 +1,601 @@
/*
* functions for dotfile handling (options, history, ...)
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*
* To add a new option, do the following:
* -> set default in session_init()
* -> add entry in settings_option_set()
* -> add entry in settings_options_write()
* -> of course, set it in gtksettings (also set_data()!) / whatever
* -> get it back in gtksettings_try()
*/
/* regular GNU system includes */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <limits.h>
/* own header files */
#include "globals.h"
#include "session.h"
#include "settings.h"
#include "calleridparser.h"
#include "util.h"
#include "callerid.h"
#include "isdn.h"
#include "isdnlexer.h"
#include "isdnparser.h"
#include "isdntree.h"
extern FILE *callerid_in;
int callerid_parse(void *session);
extern FILE *isdn_in;
int isdn_parse();
/*
* sets an option for the specified session
*
* used as callback from yyparse()
*/
void settings_option_set(session_t *session, char *option, char *value) {
int i_value = INT_MIN; /* set value to 0 or 1 if appropriate */
if (!strcmp(value, "0") || !strcasecmp(value, "false") ||
!strcasecmp(value, "off")) {
i_value = 0;
} else
if (!strcmp(value, "1") || !strcasecmp(value, "true") ||
!strcasecmp(value, "on")) {
i_value = 1;
} else
i_value = strtol(value, NULL, 0);
/* Settings */
if (i_value != INT_MIN) {
if (!strcmp(option, "HistorySize")) {
session->dial_number_history_maxlen = i_value;
}
if (!strcmp(option, "CallerIDSize")) {
session->cid_num_max = i_value;
}
if (!strcmp(option, "SaveOptions")) {
session->option_save_options = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "ExecOnIncoming")) {
free(session->exec_on_incoming);
session->exec_on_incoming = strdup(value);
}
if (!strcmp(option, "PopupOnIncoming")) {
session->option_popup = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "RecordingFormat")) {
if (!strcasecmp(value, "aiff")) {
session->option_recording_format =
(session->option_recording_format & ~RECORDING_FORMAT_MAJOR)
| RECORDING_FORMAT_AIFF;
} else { /* wav */
session->option_recording_format =
(session->option_recording_format & ~RECORDING_FORMAT_MAJOR)
| RECORDING_FORMAT_WAV;
}
}
if (!strcmp(option, "RecordingEncoding")) {
if (!strcasecmp(value, "s16")) {
session->option_recording_format =
(session->option_recording_format & ~RECORDING_FORMAT_MINOR)
| RECORDING_FORMAT_S16;
} else { /* ulaw */
session->option_recording_format =
(session->option_recording_format & ~RECORDING_FORMAT_MINOR)
| RECORDING_FORMAT_ULAW;
}
}
if (!strncmp(option, "PresetName", 10)) {
int num = strtol(&option[10], NULL, 0);
if (0 <= num && num < SESSION_PRESET_SIZE) {
free(session->preset_names[num]);
session->preset_names[num] = strdup(value);
}
}
if (!strncmp(option, "PresetNumber", 12)) {
int num = strtol(&option[12], NULL, 0);
if (0 <= num && num < SESSION_PRESET_SIZE) {
free(session->preset_numbers[num]);
session->preset_numbers[num] = strdup(value);
}
}
if (!strcmp(option, "MergeIsdnlog")) {
session->option_calls_merge = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "MergeIsdnlogDays")) {
session->option_calls_merge_max_days = i_value;
}
if (!strcmp(option, "AudioDeviceIn") &&
!strcmp(session->audio_device_name_in, "")) { /* may be overridden */
free(session->audio_device_name_in);
session->audio_device_name_in = strdup(value);
}
if (!strcmp(option, "AudioDeviceOut") &&
!strcmp(session->audio_device_name_out, "")) { /* may be overridden */
free(session->audio_device_name_out);
session->audio_device_name_out = strdup(value);
}
if (!strcmp(option, "ReleaseAudioDevices")) {
session->option_release_devices = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "IdentifyingMSN") &&
!strcmp(session->msn, "")) { /* may be overridden */
free(session->msn);
session->msn = strdup(value);
}
if (!strcmp(option, "ListenOnMSNs") &&
!strcmp(session->msns, "")) { /* may be overridden */
free(session->msns);
session->msns = strdup(value);
}
/* GUI state */
if (!strcmp(option, "ShowCallerID")) {
session->option_show_callerid = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "ShowLLCheckers")) {
session->option_show_llcheck = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "ShowControlPad")) {
session->option_show_controlpad = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "Muted")) {
session->option_muted = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "RecordToFile")) {
session->option_record = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "RecordLocalChannel")) {
session->option_record_local = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "RecordRemoteChannel")) {
session->option_record_remote = (i_value == 0 ? 0 : 1);
}
}
}
/*
* Read options from options file and isdn4linux config
*
* Here, we parse the config file and _change_ options. The defaults
* will be all set at init time
*/
void settings_options_read(session_t *session) {
char *homedir;
char *filename;
/* read isdn4linux config */
isdn_lexer_init(ISDN_CONFIG_FILENAME);
if (!isdn_in) {
fprintf(stderr, "Warning: Couldn't read ISDN config file.\n");
} else {
isdn_tree_node_t* node;
isdn_parse();
isdn_lexer_deinit();
if (debug > 1) {
printf("ISDN config file (%s) contents:\n", ISDN_CONFIG_FILENAME);
isdn_tree_dump();
}
/* get calls file name if possible */
node = isdn_tree;
while (node != NULL) {
if (node->type == ISDN_NODE_TYPE_SECTION &&
!strcmp(node->name, "ISDNLOG"))
{
isdn_tree_node_t* entry = node->content.section;
while (entry != NULL ) {
if (entry->type == ISDN_NODE_TYPE_ENTRY &&
!strcmp(entry->name, "LOGFILE"))
{
if (isdn_calls_filename_from_config)
free(isdn_calls_filename_from_config);
isdn_calls_filename_from_config = strdup(entry->content.value);
}
entry = entry->next;
}
}
node = node->next;
}
isdn_tree_free();
}
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
/* dotfile */
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_OPTIONS_FILENAME) < 0)
{
fprintf(stderr,
"Warning: Couldn't allocate memory for options filename.\n");
return;
}
isdn_lexer_init(filename);
if (!isdn_in) {
fprintf(stderr, "Warning: No options file available.\n");
} else {
isdn_tree_node_t* node;
isdn_parse();
isdn_lexer_deinit();
node = isdn_tree;
if (debug > 1) {
printf("Options file (%s) contents:\n", filename);
isdn_tree_dump();
}
/* actually set options */
while (node != NULL) {
switch (node->type) {
case ISDN_NODE_TYPE_ENTRY:
if (debug)
printf("Setting \"%s\" to \"%s\"...\n",
node->name, node->content.value);
settings_option_set(session, node->name, node->content.value);
break;
case ISDN_NODE_TYPE_SECTION:
fprintf(stderr, "Warning: Unexpected section \"%s\".\n", node->name);
break;
case ISDN_NODE_TYPE_SUBSECTION:
fprintf(stderr,
"Warning: Unexpected subsection \"%s\".\n", node->name);
break;
default:
fprintf(stderr, "Unknown ISDN_NODE_TYPE\n");
}
node = node->next;
}
isdn_tree_free();
}
free(filename);
}
/*
* write options to options file (in dotfile directory)
*/
void settings_options_write(session_t *session) {
int i;
char *homedir;
char *filename;
FILE *f;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (touch_dotdir())
return;
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_OPTIONS_FILENAME) < 0) {
fprintf(stderr,
"Warning: Couldn't allocate memory for options filename.\n");
return;
}
if ((f = fopen(filename, "w"))) {
fprintf(f, "# " PACKAGE " options file \n\n");
fprintf(f, "#\n# Number of dialed numbers to remember\n#\n");
fprintf(f, "HistorySize = %u\n\n", session->dial_number_history_maxlen);
fprintf(f, "#\n# Maximum number of rows Caller ID window\n#\n");
fprintf(f, "CallerIDSize = %u\n\n", session->cid_num_max);
fprintf(f, "#\n# Automatically save options on exit?\n#\n");
fprintf(f, "SaveOptions = %d\n\n", session->option_save_options);
fprintf(f, "#\n# Execute an arbitrary command on incoming call\n#\n");
fprintf(f, "ExecOnIncoming = \"%s\"\n\n", session->exec_on_incoming);
fprintf(f, "#\n# When activated, the main window will be pushed to "
"foreground\n# on incoming call\n#\n");
fprintf(f, "PopupOnIncoming = \"%d\"\n\n", session->option_popup);
fprintf(f, "#\n# Audio recording device\n#\n");
fprintf(f, "AudioDeviceIn = %s\n\n", session->audio_device_name_in);
fprintf(f, "#\n# Audio playback device, "
"may be the same as AudioDeviceIn\n#\n");
fprintf(f, "AudioDeviceOut = %s\n\n", session->audio_device_name_out);
fprintf(f, "#\n# Release audio devices in idle (\"Ready\") mode "
"(when not needed)\n#\n");
fprintf(f, "ReleaseAudioDevices = %d\n\n",session->option_release_devices);
fprintf(f, "#\n# MSN (Multiple Subscriber Number) to send to identify\n"
"# ourselves at called party\n#\n");
fprintf(f, "IdentifyingMSN = %s\n\n", session->msn);
fprintf(f, "#\n# These are the MSNs we want to listen on "
"(and accept calls)\n#\n");
fprintf(f, "ListenOnMSNs = %s\n\n", session->msns);
fprintf(f, "#\n# Show Caller ID frame in main window?\n#\n");
fprintf(f, "ShowCallerID = %d\n\n", session->option_show_callerid);
fprintf(f, "#\n# Show Line Level Checkers in main window?\n#\n");
fprintf(f, "ShowLLCheckers = %d\n\n", session->option_show_llcheck);
fprintf(f, "#\n# Show control pad (key pad etc.) in main window?\n#\n");
fprintf(f, "ShowControlPad = %d\n\n", session->option_show_controlpad);
fprintf(f, "#\n# Turn on to make the other party receive silence\n#\n");
fprintf(f, "Muted = %d\n\n", session->option_muted);
fprintf(f, "#\n# Record Audio stream to file?\n#\n");
fprintf(f, "RecordToFile = %d\n\n", session->option_record);
fprintf(f, "#\n# When RecordToFile is set, record local channel?\n#\n");
fprintf(f, "RecordLocalChannel = %d\n\n", session->option_record_local);
fprintf(f, "#\n# When RecordToFile is set, record remote channel?\n#\n");
fprintf(f, "RecordRemoteChannel = %d\n\n", session->option_record_remote);
fprintf(f, "#\n# Recording file format\n"
"# (\"wav\" for Microsoft WAV / "
"\"aiff\" for Apple/SGI AIFF)\n#\n");
fprintf(f, "RecordingFormat = \"%s\"\n\n",
(session->option_recording_format & RECORDING_FORMAT_MAJOR) ==
RECORDING_FORMAT_WAV ? "wav" : "aiff");
fprintf(f, "#\n# Recording file encoding\n"
"# (\"ulaw\" for uLaw / \"s16\" for 16-bit signed)\n#\n");
fprintf(f, "RecordingEncoding = \"%s\"\n\n",
(session->option_recording_format & RECORDING_FORMAT_MINOR) ==
RECORDING_FORMAT_S16 ? "s16" : "ulaw");
fprintf(f, "#\n# Preset Names and Numbers\n#\n");
for (i = 0; i < SESSION_PRESET_SIZE; i++) {
fprintf(f, "PresetName%d = \"%s\"\n", i, session->preset_names[i]);
fprintf(f, "PresetNumber%d = \"%s\"\n", i, session->preset_numbers[i]);
}
fprintf(f, "\n");
fprintf(f,
"#\n# Merge isdnlog callerid history to local history at startup?\n#\n");
fprintf(f, "MergeIsdnlog = %d\n\n", session->option_calls_merge);
fprintf(f, "#\n# Get data from this number of last days when retrieving "
"data from\n"
"# isdnlog at startup\n"
"# (set to 0 if you prefer an unlimited number of days)\n#\n");
fprintf(f, "MergeIsdnlogDays = %d\n\n",
session->option_calls_merge_max_days);
if (fclose(f) == EOF) {
fprintf(stderr, "Warning: Couldn't close options file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: Can't write to options file.\n");
}
free(filename);
}
/* Read history file and set dial combo box */
void settings_history_read(session_t *session) {
char *homedir;
char *filename;
FILE *f;
char *lineptr = NULL;
size_t linesize = 0;
ssize_t got;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_HISTORY_FILENAME) < 0) {
fprintf(stderr,
"Warning: Couldn't allocate memory for history filename.\n");
return;
}
if (debug)
fprintf(stdout, "Info: History Filename: %s.\n", filename);
if ((f = fopen(filename, "r"))) {
do {
got = getline(&lineptr, &linesize, f);
if (lineptr[got - 1] == '\n') {
lineptr[got - 1] = '\0';
}
if (got > 0 && strlen(lineptr) > 0) {
session_history_append(session, lineptr);
if (debug)
fprintf(stdout, "Info: History Number: %s.\n", lineptr);
}
} while (got > 0);
if (fclose(f) == EOF) {
fprintf(stderr, "Warning: Couldn't close history file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: No history file available.\n");
}
free(filename);
if (lineptr) free(lineptr);
}
/*
* helper function writing the specified line s to stream f
* used as callback by settings_history_write
*/
static void settings_history_write_line(gpointer s, gpointer f) {
if (strcmp(s, "")) {
fprintf(f, "%s\n", (char*)s);
}
}
/*
* write out dial history file
*/
void settings_history_write(session_t *session) {
char *homedir;
char *filename;
FILE *f;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (touch_dotdir())
return;
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_HISTORY_FILENAME) < 0) {
fprintf(stderr,
"Warning: Couldn't allocate memory for history filename.\n");
return;
}
if ((f = fopen(filename, "w"))) {
g_list_foreach(session->dial_number_history,
settings_history_write_line, f);
if (fclose(f) == EOF) {
fprintf(stderr, "Warning: Couldn't close history file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: Can't write to history file.\n");
}
free(filename);
}
/* Read callerid history file */
void settings_callerid_read(session_t *session) {
char *homedir;
char *filename;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_CALLERID_HISTORY_FILENAME) < 0) {
fprintf(stderr, "Warning: "
"Couldn't allocate memory for caller id history filename.\n");
return;
}
if ((callerid_in = fopen(filename, "r"))) {
callerid_parse(session);
if (fclose(callerid_in) == EOF) {
fprintf(stderr, "Warning: Couldn't close callerid history file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: No caller id history file available.\n");
}
free(filename);
}
/*
* write out callerid history file
*/
void settings_callerid_write(session_t *session) {
char *homedir;
char *filename;
FILE *f;
int akt_line;
gchar *date;
gchar *type;
gchar *from;
gchar *to;
gchar *duration;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (touch_dotdir())
return;
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_CALLERID_HISTORY_FILENAME) < 0) {
fprintf(stderr, "Warning: "
"Couldn't allocate memory for callerid history filename.\n");
return;
}
if ((f = fopen(filename, "w"))) {
for (akt_line = 0; akt_line < session->cid_num; akt_line++)
{
gtk_clist_get_text(GTK_CLIST(session->cid_list), akt_line,
CID_COL_TIME, &date);
gtk_clist_get_pixtext(GTK_CLIST(session->cid_list), akt_line,
CID_COL_TYPE, &type, NULL, NULL, NULL);
gtk_clist_get_text(GTK_CLIST(session->cid_list), akt_line,
CID_COL_FROM, &from);
gtk_clist_get_text(GTK_CLIST(session->cid_list), akt_line,
CID_COL_TO, &to);
gtk_clist_get_text(GTK_CLIST(session->cid_list), akt_line,
CID_COL_DURATION, &duration);
fprintf (f, "%-19s|%-3s|%-20s|%-20s|%-10s\n",
date, type, from, to, duration);
if (debug > 1)
fprintf(stderr, "%-19s|%-3s|%-20s|%-20s|%-10s\n",
date, type, from, to, duration);
}
if (fclose(f) == EOF) {
fprintf(stderr, "Warning: Couldn't close callerid history file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: Can't write to callerid history file.\n");
}
free(filename);
}

40
src/settings.h Normal file
View File

@ -0,0 +1,40 @@
/*
* functions for dotfile handling (options, history, ...)
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* own header files */
#include "session.h"
#define SETTINGS_OPTIONS_FILENAME "options"
#define SETTINGS_HISTORY_FILENAME "history"
#define SETTINGS_CALLERID_HISTORY_FILENAME "callerid"
void settings_option_set(session_t *session, char *option, char *value);
void settings_options_read(session_t *session);
void settings_options_write(session_t *session);
void settings_history_read(session_t *session);
void settings_history_write(session_t *session);
void settings_callerid_read(session_t *session);
void settings_callerid_write(session_t *session);

408
src/sound.c Normal file
View File

@ -0,0 +1,408 @@
/*
* OSS sound handling functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
/* GNU headers */
#include <stdio.h>
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <math.h>
#include <errno.h>
#include <sys/soundcard.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <string.h>
/* own header files */
#include "globals.h"
#include "sound.h"
int default_audio_priorities[] = {AFMT_S16_LE,/* try formats in this order */ \
AFMT_S16_BE,\
AFMT_U16_LE,\
AFMT_U16_BE,\
AFMT_U8,\
AFMT_S8,\
/* ulaw at last because no native soundcard support assumed */ \
AFMT_MU_LAW,\
0}; /* end of list */
/*
* common initialization for a specific audio device
*
* NOTE: Assumes opened device, but leaves it in a state not able for further
* use when not successful. The device has to be closed and opened again.
*
* input: audio_fd: valid file descriptor of an audio device,
* format, number of channels, requested sampling rate
* requested fragment sizes
*
* returns: 0 if successful, non-zero otherwise
*
* output: speed: actually sampling rate
* fragment_size: actually fragment size for this device
*
*/
int init_audio_device(int audio_fd, int format, int channels, int *speed,
int *fragment_size) {
int temp_format;
int temp_channels;
int temp_speed;
int formats_mask;
int fragment_arg;
/* set fragment size */
fragment_arg = 0x7FFF0000 + logb(*fragment_size);
if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_arg)) {
perror("SNDCTL_DSP_SETFRAGMENT");
return(-1);
}
/* query supported audio formats */
if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &formats_mask) == -1) {
perror("SNDCTL_DSP_GETFMTS");
return(-1);
}
if (!(formats_mask & format)) { /* requested format not supported */
return(-1); /* caller should try another one */
}
/* audio format */
temp_format = format;
if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &temp_format) == -1) {
perror("SNDCTL_DSP_SETFMT");
return(-1);
}
/* number of channels */
temp_channels = channels;
if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &temp_channels) == -1) {
perror("SNDCTL_DSP_CHANNELS");
return(-1);
}
if (temp_channels != channels) {
fprintf(stderr, "Error: %d not supported as number of channels", channels);
return(-1);
}
/* sampling rate */
temp_speed = *speed;
if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &temp_speed) == -1) {
perror("SNDCTL_DSP_SPEED");
/* rarely returned because of oss' liberal use of other possible speeds */
return(-1);
}
*speed = temp_speed; /* actually used speed */
/* "verify" fragment size:
* let the driver actually calculate the fragment size
*/
if (ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_arg)) {
perror("SNDCTL_DSP_GETBLKSIZE");
return(-1);
}
if (fragment_arg != *fragment_size)
fprintf(stderr, "Note: Using non-default fragment size %d.\n",
fragment_arg);
*fragment_size = fragment_arg;
return 0;
}
/*
* opens the audio device(s). if in_audio_device_name and out_audio_device_name
* are equal, full duplex mode is assumed
*
* input: in_audio_device_name, out_audio_device_name: strings
* channels: requestes number of channels (1 / 2)
* format_priorities: list of sorted integers with valid sound formats
* (e.g. AFMT_U8). the first working one will be used
* speed_in, speed_out: requested speeds (equal for full duplex)
*
* returns: 0 if successful
* -1 if not successful
*
* output:
* audio_fd_in, audio_fd_out: file descriptors
* fragment_size_in, fragment_size_out: device buffer fragment sizes
* format_in, format_out: actually used formats
* speed_in, speed_out: actually used speeds
*/
int open_audio_devices(char *in_audio_device_name,
char *out_audio_device_name,
int channels, int *format_priorities,
int *audio_fd_in, int *audio_fd_out,
int *fragment_size_in, int *fragment_size_out,
int *format_in, int *format_out,
int *speed_in, int *speed_out) {
int audio_fd;
int initresult;
int capabilities;
int *priority;
/* try to open the sound device */
if (strcmp(in_audio_device_name, out_audio_device_name) == 0) {
/* same device for input and output: full duplex */
for (initresult = -1, priority = format_priorities;
priority && initresult; priority++) { /* try different formats */
if ((audio_fd = open(in_audio_device_name, O_RDWR | O_NONBLOCK, 0))
== -1) {
perror(in_audio_device_name);
return(-1);
}
/* device is in non-blocking mode now */
*audio_fd_in = audio_fd;
*audio_fd_out = audio_fd;
/* set device to full duplex mode */
if (ioctl(audio_fd, SNDCTL_DSP_SETDUPLEX, 0)) {
perror("SNDCTL_DSP_SETDUPLEX");
return(-1);
}
if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &capabilities)) {
perror("SNDCTL_DSP_GETCAPS");
return(-1);
}
if (!(capabilities & DSP_CAP_DUPLEX)) {
fprintf(stderr, "Error: device doesn't support full duplex mode\n");
return(-1);
}
/* *speed_in assumed to be equal to *speed_out */
*format_in = *priority; /* get new format to try */
initresult = init_audio_device(audio_fd, *format_in, channels, speed_in,
fragment_size_in);
if (initresult) /* let's retry (and re-open) */
close_audio_devices(*audio_fd_in, *audio_fd_out);
}
*format_out = *format_in;
*speed_out = *speed_in;
*fragment_size_out = *fragment_size_in;
return initresult;
} else {
/* different devices for input and output */
for (initresult = -1, priority = format_priorities;
initresult && priority; priority++) {
if ((audio_fd = open(in_audio_device_name, O_RDONLY | O_NONBLOCK, 0)) ==
-1) {
perror(in_audio_device_name);
return(-1);
}
/* device is in non-blocking mode now */
*audio_fd_in = audio_fd;
*format_in = *priority;
initresult = init_audio_device(audio_fd, *format_in, channels, speed_in,
fragment_size_in);
if (initresult) /* let's retry (and re-open) */
if (close(audio_fd)) {
perror("close audio in device");
return -1;
}
}
if (initresult) return initresult; /* no chance */
for (initresult = -1, priority = format_priorities;
initresult && priority; priority++) {
if ((audio_fd = open(out_audio_device_name, O_WRONLY | O_NONBLOCK, 0))
== -1) {
perror(out_audio_device_name);
if (close(*audio_fd_in)) { /* error -> close audio_in device */
perror("close audio in device");
}
return(-1);
}
/* device is in non-blocking mode now */
*audio_fd_out = audio_fd;
*format_out = *priority;
initresult = init_audio_device(audio_fd, *format_out, channels,
speed_out, fragment_size_out);
if (initresult) /* let's retry (and re-open) */
if (close(audio_fd)) {
perror("close audio out device");
return -1;
}
}
return initresult;
}
}
/*
* stops audio playback and recording on specified file descriptors
*/
int audio_stop(int audio_fd_in, int audio_fd_out) {
/* Instead of ioctl SNDCTL_DSP_RESET, OSS Programmer's Guide recommends
* closing and reopening the devices (-> close/open_audio_devices).
* Here, we flush the input buffer and use SNDCTL_DSP_RESET
* to clean up for further recording, but on restart, old input comes again.
*/
int result;
int frag_size;
char *buf; /* temporary allocated buffer */
struct timeval tv;
fd_set fds;
int num; /* number of file descriptors with data (0/1) */
/* flush input buffer */
if (ioctl(audio_fd_in, SNDCTL_DSP_GETBLKSIZE, &frag_size))
fprintf(stderr, "Error obtaining audio input fragment size "
"with SNDCTL_DSP_GETBLKSIZE in audio_stop().\n");
else {
buf = (char *) malloc(frag_size);
tv.tv_sec = 0; /* return immediately */
tv.tv_usec = 0;
do {
FD_ZERO(&fds);
FD_SET(audio_fd_in, &fds);
num = select(FD_SETSIZE, &fds, 0, 0, &tv); /* return immediately */
if (num > 0)
read(audio_fd_in, buf, frag_size);
} while (num > 0);
if (num == -1)
perror("select at audio_stop");
free(buf);
}
/* stop device */
if (audio_fd_in == audio_fd_out)
result = ioctl(audio_fd_in, SNDCTL_DSP_RESET, 0);
else
result = ioctl(audio_fd_in, SNDCTL_DSP_RESET, 0) |
ioctl(audio_fd_out, SNDCTL_DSP_RESET, 0);
return result;
}
/*
* Closes specified input/output file descriptors
* returns 0 on success, -1 on error
*/
int close_audio_devices(int audio_fd_in, int audio_fd_out) {
audio_stop(audio_fd_in, audio_fd_out);
if (close(audio_fd_in) == -1) {
perror("close audio device");
return -1;
}
if (audio_fd_in != audio_fd_out)
if (close(audio_fd_out) == -1) {
perror("close audio device");
return -1;
}
return 0;
}
/*
* returns number of bytes per sample for the specified
* OSS format (e.g. AFMT_U8)
*
* returns >= 1 on success, 0 otherwise (when format not supported)
*/
int sample_size_from_format(int format) {
switch(format) {
case AFMT_U8:
case AFMT_S8:
case AFMT_MU_LAW:
return 1;
case AFMT_S16_LE:
case AFMT_S16_BE:
case AFMT_U16_LE:
case AFMT_U16_BE:
return 2;
default:
return 0;
}
}
/*
* returns the number of available fragents that can be read immediately
* from specified sound device file descriptor fd
*/
int audio_get_read_fragments_number(int fd) {
audio_buf_info info;
if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
perror("SNDCTL_DSP_GETISPACE");
}
return info.fragments;
}
/*
* returns the total number of fragents available for OSS at
* specified sound device file descriptor fd for reading
*/
int audio_get_read_fragments_total(int fd) {
audio_buf_info info;
if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
perror("SNDCTL_DSP_GETISPACE");
}
return info.fragstotal;
}
/*
* returns the number of fragents that can be written (non-blocking) to
* specified sound device file descriptor fd
*/
int audio_get_write_fragments_number(int fd) {
audio_buf_info info;
if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) == -1) {
perror("SNDCTL_DSP_GETOSPACE");
}
return info.fragments;
}
/*
* returns the total number of fragents available for OSS at
* specified sound device file descriptor fd for writing
*/
int audio_get_write_fragments_total(int fd) {
audio_buf_info info;
if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) == -1) {
perror("SNDCTL_DSP_GETOSPACE");
}
return info.fragstotal;
}

47
src/sound.h Normal file
View File

@ -0,0 +1,47 @@
/*
* OSS sound handling functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <sys/soundcard.h>
#define DEFAULT_FRAGMENT_SIZE 1024
#define DEFAULT_AUDIO_DEVICE_NAME_IN "/dev/dsp"
#define DEFAULT_AUDIO_DEVICE_NAME_OUT "/dev/dsp"
extern int default_audio_priorities[];
int init_audio_device(int audio_fd, int format, int channels, int *speed,
int *fragment_size);
int open_audio_devices(char *in_audio_device_name,
char *out_audio_device_name,
int channels, int *format_priorities,
int *audio_fd_in, int *audio_fd_out,
int *fragment_size_in, int *fragment_size_out,
int *format_in, int *format_out,
int *speed_in, int *speed_out);
int close_audio_devices(int audio_fd_in, int audio_fd_out);
int audio_stop(int audio_fd_in, int audio_fd_out);
int sample_size_from_format(int format);
int audio_get_read_fragments_number(int fd);
int audio_get_read_fragments_total(int fd);
int audio_get_write_fragments_number(int fd);
int audio_get_write_fragments_total(int fd);

365
src/util.c Normal file
View File

@ -0,0 +1,365 @@
/*
* miscellaneous glibc extending functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
/* regular GNU system includes */
#include <stdio.h>
#include <unistd.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <string.h>
#include <time.h>
#include <pwd.h>
#include <sys/stat.h>
#include <errno.h>
/* own header files */
#include "globals.h"
#include "util.h"
/* declared in globals.h, defined here */
int debug = 0;
/* Subtract the `struct timeval' values X and Y,
* storing the result in RESULT.
* Return 1 if the difference is negative, otherwise 0.
*/
int timeval_subtract (struct timeval *result,
struct timeval *x,
struct timeval *y) {
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_usec < y->tv_usec) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
y->tv_usec -= 1000000 * nsec;
y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
y->tv_usec += 1000000 * nsec;
y->tv_sec -= nsec;
}
/* Compute the time remaining to wait.
tv_usec is certainly positive. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_usec = x->tv_usec - y->tv_usec;
/* Return 1 if result is negative. */
return x->tv_sec < y->tv_sec;
}
/* sleeps usecs microseconds (will be interrupted by signals) */
void ant_sleep(int usecs) {
struct timespec requested;
struct timespec remaining;
requested.tv_sec = 0;
requested.tv_nsec = usecs * 1000;
nanosleep(&requested, &remaining);
}
/*
* convert vanity number (case insensitive: 'b','B' -> '2') in-place
*/
char *un_vanity(char *s) {
char *temp = s;
while (*temp) {
switch (*temp) {
case 'a': case 'b': case 'c': case 'A': case 'B': case 'C':
*temp = '2';
break;
case 'd': case 'e': case 'f': case 'D': case 'E': case 'F':
*temp = '3';
break;
case 'g': case 'h': case 'i': case 'G': case 'H': case 'I':
*temp = '4';
break;
case 'j': case 'k': case 'l': case 'J': case 'K': case 'L':
*temp = '5';
break;
case 'm': case 'n': case 'o': case 'M': case 'N': case 'O':
*temp = '6';
break;
case 'p': case 'q': case 'r': case 's':
case 'P': case 'Q': case 'R': case 'S':
*temp = '7';
break;
case 't': case 'u': case 'v': case 'T': case 'U': case 'V':
*temp = '8';
break;
case 'w': case 'x': case 'y': case 'z':
case 'W': case 'X': case 'Y': case 'Z':
*temp = '9';
break;
}
temp++;
}
return s;
}
/*
* returns a string representing the time difference between the
* specified times
*
* NOTE: caller has to free() the returned string itself.
*/
char *timediff_str(time_t time1, time_t time0) {
int duration;
char *buf;
int hours;
int minutes;
int seconds;
buf = (char *)malloc(9);
duration = (int)difftime(time1, time0);
seconds = duration % 60;
minutes = (duration / 60) % 60;
hours = duration / (60 * 60);
if (snprintf(buf, 9, "%02d:%02d:%02d", hours, minutes, seconds) >= 9)
buf[8] = '\0';
return buf;
}
/*
* returns a string with the specified long int as content
*
* NOTE: caller has to free() the returned memory
*/
char *ltostr(long int i) {
char *s;
if (asprintf(&s, "%ld", i) < 0)
return NULL;
return s;
}
/*
* forks and executes given command (with arguments) via sh
*/
void execute(char *command) {
pid_t result = fork();
char *argv[] = {"sh", "-c", command, NULL};
if (result == -1) { /* error */
fprintf(stderr, "Fork error.\n");
} else if (result == 0) { /* we are the child */
if (execvp("sh", argv)) {
fprintf(stderr, "Exec error.\n");
exit(1);
}
}
}
/*
* return home dir, returned buffer must not be freed but will be overwritten
* by subsequent calls (or calls to getpwuid())
* returns NULL on error
*/
char *get_homedir(void) {
struct passwd *user;
if (!(user = getpwuid(getuid()))) {
return NULL;
}
if (user->pw_dir == NULL || !strcmp(user->pw_dir, "") ||
user->pw_dir[strlen(user->pw_dir) - 1] == '/') {
return NULL;
}
return user->pw_dir;
}
/*
* When the specified directory doesn't exist, create it (755)
* (used by options and history write functions)
* returns 0 on success, -1 otherwise
*/
int touch_dir(char *dirname) {
if (!mkdir(dirname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
return 0;
if (errno == EEXIST) return 0;
return -1;
}
/*
* Creates dotdir (in homedir) if it doesn't exist
*
* returns 0 on success, -1 otherwise
*/
int touch_dotdir(void) {
char *homedir;
char *filename;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return -1;
}
if (asprintf(&filename, "%s/." PACKAGE, homedir) < 0) {
fprintf(stderr,
"Warning: Couldn't allocate memory for configuration directory.\n");
return -1;
}
if (touch_dir(filename) < 0) {
if (debug)
fprintf(stderr, "Warning: Can't reach configuration directory.\n");
return -1;
}
free(filename);
return 0;
}
/*
* in the string s, substitute x by y
* NOTE: s is dynamically allocated and will be re-allocated by this function
*
* returns the number of substitutions
*/
int substitute(char **s, char *x, char *y) {
int result = 0;
char *pos;
char *temp;
while ((pos = strstr(*s, x))) { /* while we found something: substitute */
*pos = '\0';
asprintf(&temp, "%s%s%s", *s, y, &pos[strlen(x)]);
free(*s);
*s = temp;
result ++;
}
return result;
}
/*
* returns the date in the form of only digits, e.g. YYYYMMDDhhmmss
* the resulting string is dynamically allocated and should be deallocated
* with free().
*
* returns NULL on error
*/
char *util_digitstime(time_t *time) {
char *s = (char *)malloc(15);
int len;
s[0] = '\1';
len = strftime(s, 15, "%Y%m%d%H%M%S", localtime(time));
if (len == 0 && s[0] != '\0') {
return NULL;
} else {
return s;
}
}
/*
* returns a string where all occurences of the character c are removed
* from the input string s
* NOTE: caller has to free() the result
*/
char* stripchr(char* s, char c) {
int count = 1; /* trailing space */
char* temp;
char* result;
for (temp = s; *temp; temp++) {
if (*temp != c)
count++;
}
if ((result = (char*) malloc (count))) {
temp = result;
while (*s) {
if (*s != c) {
*temp = *s;
temp ++;
}
s++;
}
*temp = '\0';
}
return result;
}
/*
* returns the filename extension for the specified file / path
* or NULL on problems
*/
char* filename_extension(char* fn) {
char* result = strrchr(fn, '.');
if (result) {
result++;
if (strchr(result, '/')) {
result = NULL;
}
}
return result;
}
/*
* saves the current codeset globally for further calls to output_codeset_set()
* -> returns 0 on success, -1 otherwise (default: sets codeset to "UTF-8")
*/
static char* output_codeset = NULL; /* the saved codeset */
int output_codeset_save(void) {
if (!(output_codeset = bind_textdomain_codeset(PACKAGE, NULL))) {
output_codeset = strdup("UTF-8");
return -1;
} else {
output_codeset = strdup(output_codeset);
return 0;
}
}
/*
* sets the output codeset GNU gettext produces while translating messages
* if codeset == 0, a saved values will be used.
* (save with: output_codeset_save())
* -> returns 0 on success, -1 otherwise
*/
int output_codeset_set(char* codeset) {
if (!codeset)
codeset = output_codeset;
if (!bind_textdomain_codeset(PACKAGE, codeset)) {
fprintf(stderr, "Error setting gettext output codeset to %s.\n", codeset);
return -1;
}
return 0;
}

56
src/util.h Normal file
View File

@ -0,0 +1,56 @@
/*
* miscellaneous glibc extending functions
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _ANT_UTIL_H
#define _ANT_UTIL_H
#include "config.h"
/* regular GNU system includes */
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <time.h>
#define SHORT_INTERVAL 10000
/* 10 milliseconds */
int timeval_subtract (struct timeval *result,
struct timeval *x,
struct timeval *y);
void ant_sleep(int usecs);
char *un_vanity(char *s);
char *timediff_str(time_t time1, time_t time0);
char *ltostr(long int i);
void execute(char *command);
char *get_homedir(void);
int touch_dir(char *dirname);
int touch_dotdir(void);
int substitute(char **s, char *x, char *y);
char *util_digitstime(time_t *time);
char* stripchr(char* s, char c);
char* filename_extension(char* fn);
int output_codeset_save(void);
int output_codeset_set(char* codeset);
#endif /* util.h */