wmnotify: Remove from repository.

It appears to still be maintained by the original author.  A newer version
(1.0.1) is available at:
http://www.hugovil.com/projet.php?proj=wmnotify&lang=en_US
This commit is contained in:
Doug Torrance 2016-12-26 21:54:31 +00:00 committed by Carlos R. Mafra
parent 153a87506d
commit d34152043b
37 changed files with 0 additions and 5747 deletions

View file

@ -1 +0,0 @@
Author: Hugo Villeneuve (hugo@hugovil.com)

View file

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General
Public License instead of this License.

View file

@ -1,128 +0,0 @@
2011-03-16 Hugo Villeneuve <hugo@hugovil.com>
* Prepared package for Ubuntu PPA.
2010-09-07 Hugo Villeneuve <hugo@hugovil.com>
* Added SSLv3 and TLSv1 methods in addition to SSLv2.
* Added optional IMAP folder.
* Removed custom Makefile rule for silent compilation and now using
AM_SILENT_RULES.
2009-10-21 Hugo Villeneuve <hugo@hugovil.com>
* Do not permit to enable use_ssl=1 in configuration file if SSL
support is not compiled in.
2009-01-03 Hugo Villeneuve <hugo@hugovil.com>
* Fixed a problem when receiving more than 1024 bytes
from IMAP4 server (increased buffer from 1024 to 10240 bytes).
2006-02-19 Bobby <jborgdor at cs dot uu dot nl>
* Replaced deprecated function OpenSSL_add_all_algorithms() with
SSL_library_init(), because OpenSSL_add_all_algorithms() is no
longer present in openssl-0.9.8.
2005-10-25 Hugo Villeneuve <hugo@hugovil.com>
* Added a visual notification that a double-click has been detected.
2005-09-27 Hugo Villeneuve <hugo@hugovil.com>
* Fixed a bug which closed the application if there was a network
problem in the WmnotifyGetResponse() function.
2005-06-22 Hugo Villeneuve <hugo@hugovil.com>
* Now using the same Tx and Rx buffers for POP3 and IMAP4.
* Removed autogenerated files from subversion repository.
2005-06-22 Hugo Villeneuve <hugo@hugovil.com>
* Added support for IMAP4 commands that may span multiple
packets by calling recv() until full IMAP4 response is received.
Based on comments/patches by Joffrey Pannequin and Randy.
2004-02-24 Hugo Villeneuve <hugo@hugovil.com>
* Added error checking for IMAP4 responses.
* Changed default check delay to 5 minutes.
* Added command line option to display debug messages (-d)
2004-02-01 Hugo Villeneuve <hugo@hugovil.com>
* Put common code for POP3 and IMAP4 into "network.c".
* Added SSL support via configuration file option and autoconf.
* SSL is now transparent for POP3 and IMAP4.
* Cleaned-up error messages.
2004-01-18 Hugo Villeneuve <hugo@hugovil.com>
* Changed 'AF_INET' to 'PF_INET' in socket function call (pops.c).
* Added IMAP4 basic support over SSL.
* Added 'network.c' file, which contains common routines for POP3 and
IMAP4 protocols.
2004-01-17 Hugo Villeneuve <hugo@hugovil.com>
* Added project to subversion repository.
* Added 'doc' subdirectory and updated autoconf files accordingly.
* Added the 'bootstrap' script to the distribution tarball to be
able to regenerate the autoconf output files.
* Added section in README to explain how to use eSound (ESD) when
multiple applications try to use the sound card at the same time.
* Added the Adobe Illustrator source image to the dist-tarball.
2003-04-04 Hugo Villeneuve <hugo@hugovil.com>
* Fixed a bug which caused compilation errors when 'libsndfile' was not
present. The problem was caused by 'configure.in' defining the macro
'HAVE_SNDFILE' to '0' instead of putting it into comments when
'libsndfile' was not detected. Since '#if defined(HAVE_SNDFILE)' was
used in 'sound.c', this always evaluated to 'TRUE'.
2003-04-01 Hugo Villeneuve <hugo@hugovil.com>
* Added a new rule to src/Makefile.am in order to enhance the
readability of the output generated by Make when compiling (removed the
display of source, depfile, depmod, etc).
2003-03-25 Hugo Villeneuve <hugo@hugovil.com>
* Fixed a bug with prevented the new mail animation to run when the
following sequence was encountered:
-The user double-clicked to start the external mail client
-A new E-mail is received shortly after that
-The user exit the external mail client
-The user manually check for new E-mail
-The audio notification sound is played, but no animation image is
displayed.
2003-03-24 Hugo Villeneuve <hugo@hugovil.com>
* Fixed a bug with the audible notification which was always enabled,
even when this feature was disabled in the configuration file.
* Added support for audio notification using the following sound file
formats:
AU (*.au)
WAV (*.wav)
The OSS and ALSA architectures are supported.
2003-03-10 Hugo Villeneuve <hugo@hugovil.com>
* Added xmalloc function for locally handling errors.
* Renamed src/wmgeneral.x to src/dockapp.x
* Removed src/misc.c
* Added src/common.h
* Added src/options.x
* Added src/configfile.x
* Moved src/config.h to ./config.h
* Added some comments for splint code checker
* Changed background color from yellow to grey (transparent)
* Removed the thread for animating the mailbox (moved to TimerThread)
* Removed the thread to detect double-click events in xevents.c (this is
now han dled in ProcessXlibEvents() function)
* Corrected some warnings found by splint.
2003-02-06 Hugo Villeneuve <hugo@hugovil.com>
* Added option '--enable-debug' to the configure script for having
verbose debugging messages on the console.
* Added M4 macros source files to the distribution tarball.
* Added the name of the program 'wmnotify: ' before debug messages.
* Now handling '-ERR' response from POP3 server.
* Change the case of the POP3 command 'quit' to 'QUIT'.
* Added error handling macro 'WMNOTIFY_ERR( message )'.
2003-02-05 Hugo Villeneuve <hugo@hugovil.com>
* Added some comments to 'wmgeneral.c' and removed unused functions.

View file

@ -1,229 +0,0 @@
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View file

@ -1,23 +0,0 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = gnu
SUBDIRS = src doc
## We want these in the dist tarball
EXTRA_DIST = autogen.sh \
$(ac_aux_dir)/acx_pthread.m4 \
pixmaps
ACLOCAL = aclocal -I $(ac_aux_dir)
CLEANFILES = *~
DISTCLEANFILES = .deps/*.P
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config-h.in \
stamp-h.in $(ac_aux_dir)/depcomp \
$(ac_aux_dir)/install-sh $(ac_aux_dir)/missing \
$(ac_aux_dir)/mkinstalldirs $(ac_aux_dir)/config.guess \
$(ac_aux_dir)/config.sub $(ac_aux_dir)/ltmain.sh \
$(ac_aux_dir)/compile

View file

@ -1,32 +0,0 @@
2011-03-16: wmnotify-1.0.0 has been released.
Fixes bug when receiving more than 1024 bytes from IMAP server.
Added SSLv3 and TLSv1 methods in addition to SSLv2.
Added optional IMAP folder.
See the file 'ChangeLog' for further details.
2006-02-19: wmnotify-0.3.2 has been released.
Fixes a problem when compiling wmnotify with
openssl-0.9.8.
See the file 'ChangeLog' for further details.
2005-06-22: wmnotify-0.3.1 has been released.
This is a bug fix regarding IMAP4 server responses
spanning multiple packets.
See the file 'ChangeLog' for further details.
2004-02-26: wmnotify-0.3.0 has been released.
Added support for IMAP4 servers, and SSL encryption.
See the file 'ChangeLog' for further details.
2003-04-04: wmnotify-0.2.2 has been released.
This is a bug fix regarding 'libsndfile'
See the file 'ChangeLog' for further details.
2003-03-26: wmnotify-0.2.1 has been released.
See the file 'ChangeLog' to see what has changed since last version.
2003-03-10: wmnotify-0.2 has been released.
See the file 'ChangeLog' to see what has changed since last version.
2003-02-01: wmnotify-0.1 has been released.

View file

@ -1,66 +0,0 @@
Wmnotify
Dockable email notification program for single POP3 or IMAP4 account.
Wmnotify now supports SSL.
Program launch:
If you want wmnotify to produce sounds even when another program is using
the sound card (MP3 player for example), you must use the eSound (ESD)
library. This library act as a sound mixer daemon for enabling multiple
audio applications to have access to the sound card simultaneously.
Hopefully, wmnotify doesn't need to be recompiled to use this feature.
Simply launch wmnotify like this:
esddsp wmnotify
Your other audio applications must be configured for using eSound for this
to work however. For example, with the XMMS MP3 player (version 1.2.7), you
must specify this output plugin:
eSound Output Plugin 1.2.7 [libesdout.so]
If you don't have eSound or you don't want to use it, simply launch wmnotify
like this:
wmnotify
Project website:
http://www.hugovil.com/en/wmnotify
This program was tested on the following systems:
"Linux From Scratch 4.0"
For recent project news, see the "NEWS" file.
Building wmnotify:
------------------
For generic installation instructions, see the "INSTALL" file.
If you are building from the subversion repository, first run the "autogen.sh" script.
If you are seeing this error message during configure:
"Can't find X11 library"
it means you are missing some libX11 files.
On Debian-based systems, install libX11-dev with this command:
apt-get install libX11-dev
If you are seeing this error message during configure:
"Can't find header file for library Xpm"
it means you are missing some libxpm files.
On Debian-based systems, install libxpm-dev with this command:
apt-get install libxpm-dev
If you are seeing this error message during configure:
"Can't find header file for library Xext"
it means you are missing some libxext files.
On Debian-based systems, install libxext-dev with this command:
apt-get install libxext-dev
If you want to use SSL for your POP or IMAP account, you must install openssl:
http://www.openssl.org/
On Debian-based systems, install libsndfile with this command:
apt-get install libssl-dev
If you want to have support for audio notification using WAV or AU sound files,
you must install the 'libsndfile' library:
http://www.zip.com.au/~erikd/libsndfile/
On Debian-based systems, install libsndfile with this command:
apt-get install libsndfile1-dev

View file

@ -1,20 +0,0 @@
TODO
====
o Add support for standard file ~/.mailrc (POSIX) for settings?
o Do we add support for spaces in IMAP or POP passwords?
o Set real application name instead of using argv[0]...
o Create a test application to send responses in multiple
packets.
o Add support for multiple accounts;
o Add support for local mailboxes;
o Implement correct method for checking new messages with
IMAP (don't use RECENT command, but NEW command);
o Implement the volume for the console beep;
o Test if the 'execcommand' variable in the configuration file points to
a valid executable (double-click action);
o In configure.in, is the check to "sys/types" necessary?
o In pop3.c, gethostbyname() blocks for a long time if network is unavailable;
Try alternative to this blocking mode (timeout value?);
o The volume setting in the configuration file is in percentage, but it is not computed
as a logarithmic function in file sound.c (dB);

View file

@ -1,68 +0,0 @@
#!/bin/sh
# autogen.sh -- Use this script to create generated files from the SVN distribution
# Taken from glib CVS
PROJECT=Wmnotify
TEST_TYPE=-f
TEST_FILE=src/wmnotify.c
ACLOCAL_FLAGS="${ACLOCAL_FLAGS} -I config"
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
ORIGDIR=`pwd`
cd ${srcdir}
DIE=0
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $PROJECT."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have automake installed to compile $PROJECT."
echo "Get ftp://sourceware.cygnus.com/pub/automake/automake-1.4.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
(libtoolize --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have libtool installed to compile $PROJECT."
echo "Visit http://www.gnu.org/software/libtool/ for more information."
DIE=1
}
if test "${DIE}" -eq 1; then
exit 1
fi
test ${TEST_TYPE} ${TEST_FILE} || {
echo "You must run this script in the top-level $PROJECT directory"
exit 1
}
case ${CC} in
*xlc | *xlc\ * | *lcc | *lcc\ *) am_opt=--include-deps;;
esac
aclocal ${ACLOCAL_FLAGS}
#libtoolize --force --copy
# Optionally feature autoheader
(autoheader --version) < /dev/null > /dev/null 2>&1 && autoheader
automake --add-missing --copy ${am_opt}
autoconf
cd ${ORIGDIR}
rm -rf autom4te.cache

View file

@ -1,226 +0,0 @@
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
dnl
dnl This macro figures out how to build C programs using POSIX
dnl threads. It sets the PTHREAD_LIBS output variable to the threads
dnl library and linker flags, and the PTHREAD_CFLAGS output variable
dnl to any special C compiler flags that are needed. (The user can also
dnl force certain compiler flags/libs to be tested by setting these
dnl environment variables.)
dnl
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
dnl multi-threaded programs (defaults to the value of CC otherwise).
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
dnl
dnl If you are only building threads programs, you may wish to
dnl use these variables in your default LIBS, CFLAGS, and CC:
dnl
dnl LIBS="$PTHREAD_LIBS $LIBS"
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
dnl CC="$PTHREAD_CC"
dnl
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE
dnl to that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
dnl
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands
dnl to run it if it is not found. If ACTION-IF-FOUND is not specified,
dnl the default action will define HAVE_PTHREAD.
dnl
dnl Please let the authors know if this macro fails on any platform,
dnl or if you have any other suggestions or comments. This macro was
dnl based on work by SGJ on autoconf scripts for FFTW (www.fftw.org)
dnl (with help from M. Frigo), as well as ac_pthread and hb_pthread
dnl macros posted by AFC to the autoconf macro repository. We are also
dnl grateful for the helpful feedback of numerous users.
dnl
dnl @version $Id: acx_pthread.m4,v 1.3 2002/12/12 23:15 ac-archive-0.5.39 $
dnl @author Steven G. Johnson <stevenj@alum.mit.edu> and Alejandro Forero Cuervo <bachue@bachue.com>
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_SAVE
AC_LANG_C
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# pthread: Linux, etcetera
# --thread-safe: KAI C++
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthread or
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[acx_pthread_ok=yes])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: threads are created detached by default
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
AC_MSG_CHECKING([for joinable pthread attribute])
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_JOINABLE;],
ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
if test x"$ok" = xunknown; then
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_UNDETACHED;],
ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
fi
if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
[Define to the necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_RESULT(${ok})
if test x"$ok" = xunknown; then
AC_MSG_WARN([we do not know how to create joinable pthreads])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with cc_r
AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD

View file

@ -1,113 +0,0 @@
# configure.ac -- Process this file with autoconf to produce configure.
dnl Initialization stuff.
AC_INIT(wmnotify, 1.0.0)
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_SRCDIR(src/wmnotify.c)
AM_CONFIG_HEADER(config.h:config-h.in)
dnl Checking if the NEWS file has been updated to reflect the current version.
AM_INIT_AUTOMAKE(check-news)
AM_SILENT_RULES([yes])
dnl Testing the C compiler.
AM_PROG_CC_C_O
AC_LANG_C
dnl Checking for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(stdlib.h unistd.h errno.h assert.h)
AC_CHECK_HEADERS(string.h strings.h)
dnl Checking for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_PID_T
AC_TYPE_SIZE_T
dnl Basic CFLAGS values
CFLAGS="${CFLAGS} -Wall"
dnl Checking for POSIX threads library.
ACX_PTHREAD([CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$PTHREAD_LIBS $LDFLAGS" CC="$PTHREAD_CC"],
[AC_MSG_ERROR([POSIX thread support required])])
dnl Trying to locate the X window system's includes and libraries, and sets the
dnl variables x_includes and x_libraries to their locations. Also adds the
dnl required include flags to X_CFLAGS and required linking flags to X_LIBS.
AC_PATH_XTRA
CFLAGS="${CFLAGS} ${X_CFLAGS}"
LIBS="${LIBS} ${X_PRE_LIBS} ${X_LIBS} ${X_EXTRA_LIBS}"
dnl Checking for X11 library.
AC_CHECK_LIB(X11, XOpenDisplay, LIBS="${LIBS} -lX11",
echo "Can't find X11 library" ; exit 1, "${X_LIBS}")
dnl Checking for Xpm library and headers.
AC_CHECK_HEADERS(X11/xpm.h, ,echo "Can't find header file for library Xpm" ; exit 1)
AC_CHECK_LIB(Xpm, XpmCreatePixmapFromXpmImage, LIBS="${LIBS} -lXpm",
echo "Can't find Xpm library" ; exit 1, "${X_LIBS}")
dnl Checking for Xext library and headers.
AC_CHECK_HEADERS(X11/extensions/shape.h, ,
echo "Can't find header file for library Xext" ; exit 1)
AC_CHECK_LIB(Xext, XShapeCombineMask, LIBS="${LIBS} -lXext",
echo "Can't find Xext library" ; exit 1, "${X_LIBS}")
dnl Checks for libsndfile
AC_ARG_ENABLE(libsndfile,
[ --enable-libsndfile Enable libsndfile support for audible notification (default=yes)],
[ac_cv_enable_libsndfile=$enableval], [ac_cv_enable_libsndfile=yes])
AC_MSG_CHECKING([whether to use libsndfile])
if test x$ac_cv_enable_libsndfile = xyes; then
AC_MSG_RESULT(yes)
PKG_CHECK_MODULES([SNDFILE], sndfile >= 1.0.2, :, ac_cv_enable_libsndfile=no)
if test x$ac_cv_enable_libsndfile = xyes; then
AC_DEFINE([HAVE_SNDFILE],1,[Set to 1 to enable libsndfile support.])
fi
else
AC_MSG_RESULT(no)
fi
dnl Checks for OpenSSL
AC_ARG_ENABLE(ssl,
[ --enable-ssl Enable SSL support using OpenSSL (default=yes)],
[ac_cv_enable_ssl=$enableval], [ac_cv_enable_ssl=yes])
AC_MSG_CHECKING([whether to use OpenSSL])
if test x$ac_cv_enable_ssl = xyes; then
AC_MSG_RESULT(yes)
PKG_CHECK_MODULES([OPENSSL], openssl >= 0.9.6, :, ac_cv_enable_ssl=no)
if test x$ac_cv_enable_ssl = xyes; then
AC_DEFINE([HAVE_SSL],1,[Set to 1 to enable OpenSSL support.])
fi
else
AC_MSG_RESULT(no)
fi
CFLAGS="${CFLAGS} ${SNDFILE_CFLAGS} ${OPENSSL_CFLAGS}"
LIBS="${SNDFILE_LIBS} ${OPENSSL_LIBS} ${LIBS}"
AC_SUBST(CFLAGS)
AC_SUBST(LIBS)
AC_SUBST(ac_aux_dir)
dnl Creating output file(s)
AC_OUTPUT(Makefile src/Makefile doc/Makefile)
dnl Output the configuration summary
echo
echo "Configuration summary:"
echo
echo " Install path: ${prefix}"
echo " Compiler: ${CC}"
echo " Compiler flags: ${CFLAGS}"
echo " Linker flags: ${LIBS}"
echo " OpenSSL support: $ac_cv_enable_ssl"
echo " libsndfile support: $ac_cv_enable_libsndfile"
if test "x${ac_cv_enable_libsndfile}" = xno; then
echo
echo " WARNING: Althought the 'libsndfile' library is not mandatory, without it"
echo " you won't have audible notifications."
fi
echo
echo "Configure finished. Type 'make' to build."

View file

@ -1,9 +0,0 @@
## Makefile.am -- Process this file with automake to produce Makefile.in
man1_MANS = wmnotify.man
EXTRA_DIST = $(man1_MANS)
CLEANFILES = *~
MAINTAINERCLEANFILES = Makefile.in

View file

@ -1,143 +0,0 @@
.TH WMNOTIFY 1 "February 2004" "wmnotify" "User's Manual"
.SH NAME
wmnotify \- Dockable email notification program for single POP3 or IMAP4 account
.SH SYNOPSIS
.B wmnotify
[\fIOPTION\fR]...
.SH DESCRIPTION
\fBwmnotify\fR is a dockable application (DockApp) for the WindowMaker window
manager to periodically check a POP3 or IMAP4 email account for new messages.
If there are new messages in the mailbox, a simple animation is displayed
and an optional sound (or beep) is produced.
\fBwmnotify\fR now supports SSL encryption.
The interface is kept very simple. To manually check for new messages,
single-click on the mailbox image. To start your favorite email program,
double-click on the mailbox image.
When you double-click on the mailbox image to start your email program,
the new messages animation is stopped, assuming that you will read your new
messages. If you don't, the wmnotify program will simply continue it's
periodic checking of your email account and will restart the new messages
animation after the usual delay if new messages are unread.
By default, the interval between checks is 5 minutes, and this can be changed
in the configuration file. You can also enable audio notification as well as
specify an optional audio sound file (WAV or AU). If audio notification is
enabled but no audio sound file is specified, a beep will be produced. There is
an option in the configuration file to adjust the volume of the sound file.
.SH "OPTIONS"
.TP
.BI "\-\^c " config-file
.B wmnotify
reads your mail account settings and preferences from the specified
configuration file. This option overrides the use of the default config file,
.IR "$HOME/.wmnotifyrc". Make sure that the alternate configuration file has
correct permissions (normally 0400) to protect your email account informations.
.TP
\fB\-d\fR
Display debugging messages.
.TP
.BI \-display " host" : display
Specifies the host and screen to be used by \fBwmnotify\fR. By default this
is obtained from the environment variable
.SB DISPLAY.
.TP
.BI \-geometry " geometry"
.RB ( *geometry )
Specifies the initial geometry of the window.
.TP
\fB\-h\fR
display usage and exit
.TP
\fB\-v\fR
output version information and exit
.SH "CONFIGURATION FILE"
.IR $HOME/.wmnotifyrc
The first time the program is run, it will check for the presence of the
configuration file in the user's home directory. If this file is not found,
wmnotify will automatically create a new one, and exit with a message telling the
user to set it's mail account settings and preferences in the new configuration file
before restarting wmnotify.
.TP
.BI "protocol " <protocol-name>
mail account protocol, POP3 or IMAP4.
.TP
.BI "imap_folder " <folder-name>
IMAP folder name (optional, default is INBOX).
.TP
.BI "use_ssl " <value>
This option controls the SSL encryption enabling/disabling. The value may be
set to "0" to disable or to "1" to enable.
.TP
.BI "server " <server-name>
mail server name (or IP address).
.TP
.BI "port " <port-number>
mail server port number (optional, default value is 110).
.TP
.BI "username " <username>
mail account username.
.TP
.BI "password " <password>
mail account password.
.TP
.BI "mailcheckdelay " <delay-in-minutes>
Mail check interval, in minutes (optional, default value is 5).
.TP
.BI "mailclient " <program>
The program to start when double-clicking on the mailbox image (optional).
.TP
.BI "enablebeep " <value>
This option controls the audio notification enabling/disabling. If this option
is enabled and the "audiofile" option below contains a valid audio file, it
will be played whenever new message(s) are detected. If "audiofile" is
commented, the console beep will be used to produce the audio notification. The
value may be set to "0" to disable or to "1" to enable (optional, default value is 0, disabled).
.TP
.BI "audiofile " <path-to-audiofile>
Path and filename of the WAV or AU audio sound file to play when new message(s)
are detected (optional).
.TP
.BI "volume " <value>
Volume value, in percent, when playing an audio file (optional, default value is
100%). This volume value is relative to the values you have set in your sound
card mixer settings. If you find the audio notification sound to be too loud,
just reduce the volume value. On the other hand, if you want to increase the
audio notification sound amplitude, just increase the volume. If you increase
the volume value to 100% and you find that it is not sufficient, then you would
have to increase the volume using your favorite sound card mixer program
(ex: with alsamixer, increase the PCM or master value).
.SH CREDITS
\fBwmnotify\fR was written by Hugo Villeneuve <hugo@hugovil.com>, based on
the WMPop3 program by Scott Holden <scotth@thezone.net>.
.SH COPYRIGHT
\fBwmnotify\fR is free; anyone may redistribute it to anyone under the terms
stated in the GNU General Public License. A copy of the license is included in
the \fBwmnotify\fR distribution. You can also browse it online at
.I http://www.gnu.org/copyleft/gpl.html

View file

@ -1,183 +0,0 @@
/* XPM */
static char * wmaker_tile_xpm[] = {
"64 64 116 2",
" c None",
". c #F6F6FF",
"+ c #F6F2FF",
"@ c #EEEEFF",
"# c #EEEAFF",
"$ c #E6EAF6",
"% c #EEE6FF",
"& c #E6E6F6",
"* c #E6E2F6",
"= c #DEE2EE",
"- c #DEDEEE",
"; c #DEDAEE",
"> c #D5DAE6",
", c #D5D6E6",
"' c #D5D2E6",
") c #CDD2DE",
"! c #CDCEDE",
"~ c #A4A5B4",
"{ c #000000",
"] c #FFFFFF",
"^ c #F6EEFF",
"/ c #E6DEF6",
"( c #DED6EE",
"_ c #D5CEE6",
": c #A4A1B4",
"< c #9C9DB4",
"[ c #A49DB4",
"} c #9C9DAC",
"| c #9C99AC",
"1 c #9499A4",
"2 c #9C95AC",
"3 c #9495A4",
"4 c #9491A4",
"5 c #8B919C",
"6 c #948DA4",
"7 c #8B8D9C",
"8 c #8B899C",
"9 c #838994",
"0 c #8B859C",
"a c #838594",
"b c #838194",
"c c #7B818B",
"d c #7B7D8B",
"e c #525562",
"f c #A49DAC",
"g c #A499AC",
"h c #9C91AC",
"i c #837D94",
"j c #525062",
"k c #9495AC",
"l c #9C99A4",
"m c #9C95A4",
"n c #9C91A4",
"o c #7B798B",
"p c #A499B4",
"q c #8B91A4",
"r c #94919C",
"s c #4A505A",
"t c #9491AC",
"u c #8B8DA4",
"v c #737983",
"w c #948D9C",
"x c #524C62",
"y c #7B758B",
"z c #4A4C5A",
"A c #737583",
"B c #4A485A",
"C c #83899C",
"D c #8B8594",
"E c #83859C",
"F c #737183",
"G c #414852",
"H c #6A717B",
"I c #4A445A",
"J c #83818B",
"K c #736D83",
"L c #7B8194",
"M c #414452",
"N c #837D8B",
"O c #6A6D7B",
"P c #73798B",
"Q c #7B7983",
"R c #7B7583",
"S c #414052",
"T c #7B7D94",
"U c #6A697B",
"V c #39404A",
"W c #626973",
"X c #73758B",
"Y c #73717B",
"Z c #393C4A",
"` c #6A7183",
" . c #626573",
".. c #6A6D83",
"+. c #736D7B",
"@. c #6A657B",
"#. c #62697B",
"$. c #6A6973",
"%. c #62657B",
"&. c #39384A",
"*. c #6A6573",
"=. c #626173",
"-. c #313841",
";. c #5A616A",
">. c #62616A",
",. c #5A6173",
"'. c #313441",
"). c #5A5D6A",
"!. c #313041",
"~. c #5A596A",
"{. c #293441",
"]. c #525D62",
"^. c #293039",
"/. c #525962",
"(. c #292C39",
"_. c #000410",
". . + . + + + + @ + @ @ @ @ @ # # # # # $ % $ & & & & * & * * * = * - - - - - - ; - ; ; > ; , > , , , , , ' ' ' ) ' ) ! ) ! ~ { ",
"] ] . + + + + @ + ^ @ ^ @ ^ # @ # # # $ % # & % & % * & * * * = * / = / - / - ; - ; ; > ; ( > ( , ( , , ' , ' ) ' ' ! ' ! _ ~ { ",
"+ . : : : : < : [ < [ } < | } | | | 1 2 | 3 2 3 3 4 3 4 4 4 5 4 6 5 6 7 7 7 8 7 8 8 9 8 0 9 0 a a a a b a b c b b d b d d d e { ",
". + : : : [ : f } } } } g } | | | | 2 | 3 3 3 3 h 3 4 4 4 4 4 6 5 7 7 7 6 8 7 8 8 8 8 0 9 a a a 0 a b a b b b b d c d d i d j { ",
"+ + : : [ : } < [ } [ | } | | | | k l 3 k m k n 3 4 4 4 4 5 6 5 7 6 7 6 8 7 8 8 8 9 0 9 a 0 a 0 a b a b b c b d c i d i d o e { ",
"+ + : [ : } [ f } } | } | | | | k l k 2 3 3 4 3 4 4 4 4 5 6 5 6 7 7 7 8 7 8 8 8 9 0 9 0 a a a a b a b b c b d b d d d d o d j { ",
"+ + < : } [ } < } p } | | | | k l k m 3 3 h 3 4 4 4 q r 6 5 6 7 7 6 8 7 8 8 9 8 0 9 0 a a 0 a b a b c b b d b d d i d o d o s { ",
"+ @ : f < f < f | } | | | | k l k m k 3 t 3 4 4 4 4 r u 5 6 7 7 7 8 7 8 8 8 8 a 9 0 a a a a b a b b b c d b d d d d o d o o j { ",
"@ + [ } [ } } | } | | | | 3 | 3 2 3 3 4 3 4 4 4 4 5 6 5 6 7 7 7 8 7 8 8 8 9 0 9 0 a a a a b a b b c b d b d d d d o d o o v j { ",
"+ ^ < } } } p } | | | | 3 | 3 2 3 3 t 3 4 4 4 r q 6 5 6 7 7 7 8 7 8 8 8 9 0 9 0 a a a a b a b b c b d b d d d d o d o o v o s { ",
"@ @ [ } [ | } | | | | 3 | 3 2 3 3 4 3 4 4 4 4 q w 5 6 7 7 7 8 7 8 8 8 9 0 9 0 a a a a b a b b c b d b d d d d o d o o v o v x { ",
"@ ^ } } | } | | | | 3 | 3 2 3 3 4 3 4 4 4 4 r 6 5 6 7 7 7 8 7 8 8 8 8 0 9 0 a a a a b a b b b b d b d d d d o d o o o o v y s { ",
"@ @ < g } | | | | 3 | 3 2 3 3 4 3 4 4 4 4 r u 5 6 7 7 7 8 7 8 8 8 8 a 9 0 a a a a b a b b b c d b d d d d o d o o o v v y v z { ",
"@ ^ | } | | | | 3 | 3 2 3 3 4 3 4 4 4 4 r u r 6 7 7 7 8 7 8 8 8 8 a 8 0 a a a a b a b b b c i b d d d d o d o o o v o y v A z { ",
"@ # } | | | | k | 3 2 3 3 4 3 4 4 4 4 4 u r u 7 7 7 8 7 8 8 8 8 a 8 a a a a a b a b b b c i c d d d d o d o o o v o A v A A z { ",
"# @ | | | | k l 3 2 3 3 4 3 4 4 4 4 4 7 r u w 7 w 8 7 8 8 8 8 a 8 a 0 a 0 a b a b b b c i c i d i d o d o o o v o A o A y A z { ",
"# # | | | k l k 2 3 3 4 3 4 4 4 4 4 7 4 u w 7 7 8 7 8 8 8 8 a 8 a 0 a a a b a b b b c i c i d d d o d o o o v o A o A A A A B { ",
"# # | | k l k m 3 3 4 3 4 4 4 4 4 7 4 7 w 7 7 8 7 8 8 8 C D C D E a a a b a b b c b d b d d d d o d o o v o v y v A A A A F z { ",
"# # 1 2 l k m k 3 t 3 4 4 4 4 4 7 4 7 6 7 u 8 7 8 8 8 C D C D E a D a b a b b c b d b d d i d o d o o v o v y v A y A A F A B { ",
"# $ 2 | 3 2 3 3 4 3 4 4 4 4 4 7 4 7 6 7 7 8 7 8 8 8 C D C D E a a a b a b b c b d b d d d d o d o o v o v y v A A A A F A F G { ",
"$ % | 3 k 3 3 t 3 4 4 4 4 r u r u w 7 7 8 7 8 8 8 9 0 9 0 a a a a b a b b c b d b d d d d o d o o v o v y v A A A A F A F H B { ",
"% # 3 3 m 3 h 3 4 4 4 4 r u r u w 7 u 8 7 8 8 8 9 0 9 0 a a E a b a b b c b d b d d d d o d o o v o v y v A A A A F A F H F G { ",
"$ & 2 3 k 4 3 4 4 4 4 r u r u w 7 7 8 7 8 8 8 9 0 9 0 a a a a b a b b c b d b d d d d o d o o v o v y v A A A A F A F H F H I { ",
"& % 3 3 n 3 4 4 4 r q 6 5 6 7 7 7 8 7 8 8 8 9 0 9 0 a a a a b a b b J b d b d d d d o d o o o o v y v A A A A F A F F F H K G { ",
"& & 3 h 3 4 4 4 4 q w 5 6 7 7 w 8 7 8 8 8 9 0 9 0 a a a a b a b b J L d b d d d d o d o o o v v y v A A A A F A F F H H K H M { ",
"& % 4 3 4 4 4 4 5 6 5 6 7 7 7 8 7 8 8 8 9 0 9 0 a a a a b a b b J L N b d d d d o d o o o v o y v A A A A F A F F H F K H O M { ",
"& * 3 4 4 4 q r 6 5 6 7 7 7 8 7 8 8 8 C 0 9 0 a a a a b a b b b L N L d d d d o d o o o v o A v A A A A F A F F H F O H O O M { ",
"* & 4 4 4 4 r u 5 6 7 7 7 8 7 8 8 8 C D 9 0 a a a a b a b b b c N L N d N d o d o o o v o A o A y A A F A F F H F O F O K O M { ",
"& * 4 4 4 5 6 5 6 7 7 7 8 7 8 8 8 C D C 0 a a a a b a b b b c i L N d d d o d o o o v o A o A A A A F A F F H F O F O O O O M { ",
"* * 4 4 5 6 5 6 7 7 7 8 7 8 8 8 8 D C D a a a a b a b b b c i c N d d d o d o o P Q P R P A A A A F A F H F H K H O O O O O S { ",
"* * 5 4 6 5 6 7 7 7 8 7 8 8 8 8 a C D E a E a b a b b b c i c i d T d o d o o P Q P R P A R A A F A F H F H K H O K O O O U M { ",
"* = 4 6 5 6 7 7 7 8 7 8 8 8 8 a 8 D E a a a b a b b b c i c i d d d o d o o P Q P R P A A A A F A F H F H K H O O O O O U O V { ",
"= * 6 5 7 7 7 7 8 7 8 8 8 8 a 8 a E a a a b a b b J L N L N d d d o d o o v o v y v A A A A F A F H F H K H O O O O O U O W S { ",
"* / 5 7 6 7 6 8 7 8 8 8 8 a 8 a 0 a D a b a b b J L N L N d T d o d o o v o v y v A X A A F A F H F H K H O O O O O U O W U V { ",
"- = 6 7 7 7 8 7 8 8 8 8 a 8 a 0 a a a b a b b J L N L N d d d o d o o v o v y v A A A A F A F H F H K H O O O O O U O W U W S { ",
"- / 7 7 6 8 7 8 8 8 9 0 9 0 a a a a b a b b c b d b d d d d o d o o v o v y v A A A A F A F Y F H K H O O O O O U O U U W U Z { ",
"- - 7 6 8 7 8 8 8 9 0 9 0 a a 0 a b a b b c b d b d d N d o d o o v o v y v A A A A F A F Y ` H K H O O O O O U O U W W U .V { ",
"- / 7 8 7 8 8 8 9 0 9 0 a a a a b a b b c b d b d d d d o d o o v o v y v A A A A F A F Y ` Y K H O O O O O U O U W U U .W Z { ",
"- - 8 7 8 8 9 8 0 9 0 a a a a b a b b c b d b d d d d o d o o P o v y v A A A A F A F F ` Y ..H O O O O O U O U W U W .W .Z { ",
"- ; 7 8 8 8 8 a 9 0 a a a a b a b b c b d b d d d d o d o o P Q v y v A A A A F A F F H Y ..Y O +.O O O U O U W U W @.W @. .Z { ",
"; - 8 8 8 9 0 9 0 a a a a b a b b c b d b d d d d o d o o P Q P y v A A A A F A F F H F ..Y O O O O O U O U W U W @.W . . .Z { ",
"- ; 8 8 9 0 9 0 a a a a b a b b b b d b d d d d o d o o o Q P R v A A A A F A F F H F O Y O O O O O U O #.$.#.$.%.W . . . .&.{ ",
"; ; 9 8 0 9 0 a a a a b a b b b c d b d d d d o d o o o v P R P A X A A F A F F H F O F O ..O O O U O #.$.#.$.%.W *. . . .=.Z { ",
"; > 8 0 9 0 a a a a b a b b b c i b d d d d o d o o o v o R P A A A A F A F F H F O F O O O O O U O #.$.#.$.%.W . . . .=. .-.{ ",
"> ; 0 9 a a a a a b a b b b c i c d d d d o d o o o v o A P A A A A F A F Y ` Y ..Y O O O O O U O W U W U .W . . . .=. .;.&.{ ",
"; ( 9 a 0 a 0 a b a b b b c i c i d i d o d o o o v o A o A R A A F A F Y ` Y ..Y O ..O O O U O W U W U .W %. . . .=. .;.=.-.{ ",
", > 0 a a a a b a b b b c i c i d d d o d o o o v o A o A A A A F A F Y ` Y ..Y O O O O O U O W U W U .W . . . .=. .;.=.;.&.{ ",
"> ( a a 0 a b a b b c b d b d d d d o d o o v o v y v A A A A F A F H F H K H O O O O O U O W U W U .W . . . .=. .>.=.;.=.-.{ ",
", , a 0 a b a b b c b d b d d i d o d o o v o v y v A y A A F A F H F H K H O +.O O O U O W U W U .W . . . .=. .>.,.;.=.;.'.{ ",
", ( a a b a b b c b d b d d d d o d o o v o v y v A A A A F A F H F H K H O O O O O U O W U W U .W . . . .=. .>.,.>.=.;.).-.{ ",
", , a b a b c b b d b d d d d o d o o v o v y v A A A A F A F H F H K H O O O O O U O #.U W U .W . . . .=. .=.,.>.,.;.).;.'.{ ",
", , b a b b b c d b d d d d o d o o v o v y v A A A A F A F H F H K H O O O O O U O #.$.W U .W . . . .=. .=.;.>.,.>.).>.).'.{ ",
", ' a b b c b d b d d d d o d o o v o v y v A A A A F A F H F H K H O O O O O U O #.$.#.U .W . . . .=. .=.;.=.,.>.).;.).).'.{ ",
"' , b b c b d b d d d d o d o o o o v y v A A A A F A F F F H K H O O O O O U O U $.#.$. .W . . . .=. .=.;.=.;.>.).;.).).).'.{ ",
"' ' c b b d b d d d d o d o o o v v y v A A A A F A F F H H K H O O O O O U O U W #.$.%.W %. . . .=. .=.;.=.;.=.).,.).).).).!.{ ",
"' ) b b d b d d d d o d o o o v o y v A A A A F A F F H F K H O O O O O U O U W U $.%.W . . . .=. .=.;.=.;.=.).;.).).).).~.{.{ ",
") ' b d c d d d d o d o o o v o A v A A A A F A F F H F O H O O O O O U O U W U W %.W . . . .=. .>.,.>.,.>.).;.).).).).~.].!.{ ",
"' ' d c i d i d o d o o o v o A o A y A A F A F F H F O F O K O O O U O U W U W @.W *. . . .=. .>.,.>.,.>.).,.).).).).~.].~.^.{ ",
") ! b d d d d o d o o o v o A o A A A A F A F F H F O F O O O O O U O U W U W @.W . . . .=. .>.,.>.,.>.).;.).).).).~.].~./.!.{ ",
"! ' d d i d o d o o v o v y v A A A A F A F H F H K H O O O O O U O W U W U .W . . . .=. .;.=.;.=.;.).;.).).).).~.].~./.~.^.{ ",
") ! d i d o d o o v o v y v A y A A F A F H F H K H O K O O O U O W U W U .W @. . . .=. .;.=.;.=.;.).>.).).).).~.].~./.~./.(.{ ",
"! _ d d o d o o v o v y v A A A A F A F H F H K H O O O O O U O W U W U .W . . . .=. .;.=.;.=.;.).;.).).).).~.].~./.~./.e ^.{ ",
"! ~ e j e j s j j s x s z z z z B z B G B G I G M M M M M S M V S V S Z V Z Z Z Z &.Z -.&.-.&.-.'.-.'.'.'.'.!.{.!.^.!.^.(.^._.{ ",
"{ { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { "};

View file

@ -1,879 +0,0 @@
/* XPM */
static char * wmnotify_xpm[] = {
"180 122 754 2",
" c None",
". c #A49CB2",
"+ c #A4A2B7",
"@ c #9C9AAC",
"# c #9B9CB4",
"$ c #9595AC",
"% c #9C99A4",
"& c #9595A4",
"* c #9B94A4",
"= c #9491A4",
"- c #9390A3",
"; c #8B919B",
"> c #938CA3",
", c #8C8D9C",
"' c #8B899C",
") c #848994",
"! c #8B859C",
"~ c #838594",
"{ c #838093",
"] c #848194",
"^ c #7C818B",
"/ c #7B7D8B",
"( c #837D94",
"_ c #FBDD27",
": c #9C94AC",
"< c #9394A3",
"[ c #8A8C9B",
"} c #8A889A",
"| c #8B90A4",
"1 c #93909C",
"2 c #8B8D9C",
"3 c #858695",
"4 c #7C7A8C",
"5 c #88899C",
"6 c #464548",
"7 c #1C1D1D",
"8 c #010202",
"9 c #272729",
"0 c #72707C",
"a c #888AA1",
"b c #7B798B",
"c c #585659",
"d c #110E0C",
"e c #413F42",
"f c #706D6D",
"g c #323233",
"h c #6A6975",
"i c #505057",
"j c #373637",
"k c #D7D5D5",
"l c #FFFFFF",
"m c #AAA8A8",
"n c #2D2D2F",
"o c #171211",
"p c #101111",
"q c #090A0B",
"r c #868395",
"s c #D0B720",
"t c #807114",
"u c #423A0A",
"v c #2E2907",
"w c #362F08",
"x c #706211",
"y c #A5911A",
"z c #E3C823",
"A c #F9DB27",
"B c #69676C",
"C c #E8E7E7",
"D c #E2E0E0",
"E c #8F8C8C",
"F c #615E65",
"G c #161717",
"H c #404145",
"I c #63626A",
"J c #71767E",
"K c #737983",
"L c #F6D926",
"M c #5F530F",
"N c #000000",
"O c #0F0F0F",
"P c #424242",
"Q c #6E6E6E",
"R c #5B5B5B",
"S c #1B1B1B",
"T c #292406",
"U c #665910",
"V c #A4911A",
"W c #CBC9C9",
"X c #979494",
"Y c #212122",
"Z c #707482",
"` c #797686",
" . c #F5D826",
".. c #50460C",
"+. c #020202",
"@. c #7D7D7D",
"#. c #B6B6B6",
"$. c #2A2A2A",
"%. c #272206",
"&. c #655910",
"*. c #A49019",
"=. c #DEC423",
"-. c #888585",
";. c #675A10",
">. c #030303",
",. c #AFAFAF",
"'. c #E9E9E9",
"). c #0C0C0C",
"!. c #A4A4A4",
"~. c #9B9B9B",
"{. c #212121",
"]. c #040401",
"^. c #262206",
"/. c #DCC222",
"(. c #9C95AC",
"_. c #3B3B3D",
":. c #C0BFBE",
"<. c #626473",
"[. c #7C758B",
"}. c #D9BF22",
"|. c #090801",
"1. c #868686",
"2. c #E7E7E7",
"3. c #363636",
"4. c #FBFBFB",
"5. c #F9F9F9",
"6. c #DBDBDB",
"7. c #5C5C5C",
"8. c #202020",
"9. c #060501",
"0. c #262106",
"a. c #A39019",
"b. c #DDC222",
"c. c #9795A3",
"d. c #777474",
"e. c #5A5C68",
"f. c #747583",
"g. c #191919",
"h. c #F1F1F1",
"i. c #B5B5B5",
"j. c #8F8F8F",
"k. c #9C9C9C",
"l. c #1C1C1C",
"m. c #050501",
"n. c #645810",
"o. c #A38F19",
"p. c #E0C523",
"q. c #817E7D",
"r. c #FAFAFA",
"s. c #ECCF25",
"t. c #0C0B02",
"u. c #747474",
"v. c #3F3F3F",
"w. c #242424",
"x. c #FCFCFC",
"y. c #D9D9D9",
"z. c #9A9A9A",
"A. c #5A5A5A",
"B. c #1A1A1A",
"C. c #010100",
"D. c #252106",
"E. c #665A10",
"F. c #E4C823",
"G. c #848694",
"H. c #EEEDEC",
"I. c #B7B5B5",
"J. c #B9A31D",
"K. c #C5C5C5",
"L. c #BCBCBC",
"M. c #B4B4B4",
"N. c #D7D7D7",
"O. c #C2AA1E",
"P. c #7B7C8B",
"Q. c #8B7B16",
"R. c #141414",
"S. c #F7F7F7",
"T. c #161616",
"U. c #646464",
"V. c #1B1804",
"W. c #9F8C19",
"X. c #4A410C",
"Y. c #262626",
"Z. c #6D6D6D",
"`. c #DDDDDD",
" + c #CCCCCC",
".+ c #4E4E4E",
"++ c #8A7A16",
"@+ c #5F5C62",
"#+ c #747183",
"$+ c #656565",
"%+ c #A1A1A1",
"&+ c #060606",
"*+ c #DEDEDE",
"=+ c #FDFDFD",
"-+ c #727272",
";+ c #A6921A",
">+ c #9491A8",
",+ c #1F1B05",
"'+ c #686868",
")+ c #474747",
"!+ c #151303",
"~+ c #ECD025",
"{+ c #F5F5F5",
"]+ c #181818",
"^+ c #8E8E8E",
"/+ c #787878",
"(+ c #323232",
"_+ c #3E370A",
":+ c #29241F",
"<+ c #9F9C9C",
"[+ c #282828",
"}+ c #4C4C4C",
"|+ c #F8F8F8",
"1+ c #838383",
"2+ c #0D0C02",
"3+ c #EDD125",
"4+ c #6B707B",
"5+ c #612B20",
"6+ c #CB3026",
"7+ c #993226",
"8+ c #311A14",
"9+ c #F3F2F1",
"0+ c #373737",
"a+ c #939393",
"b+ c #C2C2C2",
"c+ c #C3C3C3",
"d+ c #CDB420",
"e+ c #888491",
"f+ c #49251D",
"g+ c #7A3024",
"h+ c #E92924",
"i+ c #DFDFDF",
"j+ c #390500",
"k+ c #300500",
"l+ c #333333",
"m+ c #626262",
"n+ c #A2A2A2",
"o+ c #CFCFCF",
"p+ c #080808",
"q+ c #393939",
"r+ c #2E2E2E",
"s+ c #A0A0A0",
"t+ c #530800",
"u+ c #A71000",
"v+ c #D81400",
"w+ c #BD1200",
"x+ c #8F0D00",
"y+ c #600900",
"z+ c #2F0400",
"A+ c #020000",
"B+ c #010101",
"C+ c #090909",
"D+ c #707070",
"E+ c #9F9F9F",
"F+ c #D0D0D0",
"G+ c #877715",
"H+ c #D3D3D3",
"I+ c #595959",
"J+ c #1F1F1F",
"K+ c #070100",
"L+ c #290400",
"M+ c #690A00",
"N+ c #B91100",
"O+ c #EB1600",
"P+ c #ED1600",
"Q+ c #C01200",
"R+ c #800C00",
"S+ c #520800",
"T+ c #240300",
"U+ c #121212",
"V+ c #505050",
"W+ c #7F7F7F",
"X+ c #ADADAD",
"Y+ c #4F460C",
"Z+ c #ED1F24",
"`+ c #E3E3E3",
" @ c #A3A3A3",
".@ c #999999",
"+@ c #0E0100",
"@@ c #3A0500",
"#@ c #790B00",
"$@ c #EC1600",
"%@ c #FE1800",
"&@ c #E31500",
"*@ c #B21100",
"=@ c #830C00",
"-@ c #550800",
";@ c #190200",
">@ c #717171",
",@ c #3E3E3E",
"'@ c #AAAAAA",
")@ c #FEFEFE",
"!@ c #979797",
"~@ c #575757",
"{@ c #0D0100",
"]@ c #F01700",
"^@ c #FF1800",
"/@ c #FB1800",
"(@ c #D91400",
"_@ c #A30F00",
":@ c #220300",
"<@ c #4F4F4F",
"[@ c #131003",
"}@ c #8D8D8D",
"|@ c #D1D1D1",
"1@ c #D5D5D5",
"2@ c #494949",
"3@ c #090100",
"4@ c #BA1100",
"5@ c #7B7B7B",
"6@ c #342E08",
"7@ c #5E5E5E",
"8@ c #C6C6C6",
"9@ c #070707",
"0@ c #AA1000",
"a@ c #62560F",
"b@ c #ECECEC",
"c@ c #959595",
"d@ c #680A00",
"e@ c #F81700",
"f@ c #0F0100",
"g@ c #958317",
"h@ c #101010",
"i@ c #EEEEEE",
"j@ c #848484",
"k@ c #383838",
"l@ c #EE1600",
"m@ c #F61700",
"n@ c #4D4D4F",
"o@ c #C0A91E",
"p@ c #2C2C2C",
"q@ c #C8C8C8",
"r@ c #F4F4F4",
"s@ c #5F5F5F",
"t@ c #0C0100",
"u@ c #850D00",
"v@ c #B8B8B8",
"w@ c #766812",
"x@ c #DAC022",
"y@ c #030300",
"z@ c #9E9E9E",
"A@ c #353535",
"B@ c #0B0B0D",
"C@ c #484848",
"D@ c #888888",
"E@ c #F2F2F2",
"F@ c #BDBDBD",
"G@ c #ACABC7",
"H@ c #C0BFE0",
"I@ c #C6C6E4",
"J@ c #1C1904",
"K@ c #D6D6D6",
"L@ c #969696",
"M@ c #464646",
"N@ c #060607",
"O@ c #202026",
"P@ c #5B5B6C",
"Q@ c #8A8AA4",
"R@ c #AEAECE",
"S@ c #9595B0",
"T@ c #666679",
"U@ c #373741",
"V@ c #09090A",
"W@ c #151515",
"X@ c #C7C7C7",
"Y@ c #B7B7B7",
"Z@ c #E4E4E4",
"`@ c #BABADC",
" # c #51470D",
".# c #535353",
"+# c #A7A7A7",
"@# c #1E1E1E",
"## c #070708",
"$# c #42424F",
"%# c #717186",
"&# c #A6A6C6",
"*# c #BBBBDE",
"=# c #AEAECF",
"-# c #8888A2",
";# c #5A5A6A",
"># c #2B2B33",
",# c #050506",
"'# c #131313",
")# c #878787",
"!# c #6E6111",
"~# c #1F1F24",
"{# c #5A5A6B",
"]# c #7E7E96",
"^# c #6A6A7E",
"/# c #B2B2D3",
"(# c #C0C0C0",
"_# c #818492",
":# c #342D26",
"<# c #3C342C",
"[# c #9E8B19",
"}# c #16161A",
"|# c #9191AD",
"1# c #B5B5D7",
"2# c #A9A9C8",
"3# c #3D3D48",
"4# c #4A4A57",
"5# c #8E8EA9",
"6# c #B7B7DA",
"7# c #8989A2",
"8# c #2A2A31",
"9# c #585858",
"0# c #989898",
"a# c #0E0C02",
"b# c #EFD225",
"c# c #6B727B",
"d# c #6B6C7B",
"e# c #695542",
"f# c #B0865D",
"g# c #5A4A3B",
"h# c #A27D59",
"i# c #5B616E",
"j# c #F0D425",
"k# c #9B8818",
"l# c #4E450C",
"m# c #373742",
"n# c #68687B",
"o# c #7C7C93",
"p# c #9898B5",
"q# c #ADADCD",
"r# c #737388",
"s# c #0F0C08",
"t# c #413120",
"u# c #040302",
"v# c #523D29",
"w# c #1C150E",
"x# c #707085",
"y# c #B4B4D6",
"z# c #8787A0",
"A# c #585869",
"B# c #27272F",
"C# c #616161",
"D# c #686A77",
"E# c #DAA167",
"F# c #483D32",
"G# c #C79564",
"H# c #636973",
"I# c #EED125",
"J# c #E8CD24",
"K# c #AF9A1B",
"L# c #554B0D",
"M# c #151203",
"N# c #08080A",
"O# c #0E0E10",
"P# c #34343D",
"Q# c #101013",
"R# c #2F2317",
"S# c #B18559",
"T# c #96704B",
"U# c #A67D53",
"V# c #C89664",
"W# c #312518",
"X# c #3F3F4B",
"Y# c #BABADD",
"Z# c #ABABCB",
"`# c #67677A",
" $ c #26262D",
".$ c #4F450C",
"+$ c #BC8E60",
"@$ c #D29D67",
"#$ c #DFC423",
"$$ c #B6A01C",
"%$ c #695C10",
"&$ c #5D520E",
"*$ c #070601",
"=$ c #5B442D",
"-$ c #CC9966",
";$ c #B5885B",
">$ c #A07850",
",$ c #56412B",
"'$ c #76768C",
")$ c #A1A1BF",
"!$ c #A8A8C7",
"~$ c #B6B6D9",
"{$ c #A6A6C5",
"]$ c #797990",
"^$ c #646476",
"/$ c #42424E",
"($ c #151519",
"_$ c #050505",
":$ c #B39E1C",
"<$ c #747A8C",
"[$ c #957354",
"}$ c #62657A",
"|$ c #41390A",
"1$ c #2E2217",
"2$ c #B7895C",
"3$ c #020201",
"4$ c #715539",
"5$ c #7B5D3E",
"6$ c #1C1C21",
"7$ c #030200",
"8$ c #675B10",
"9$ c #D6BC21",
"0$ c #E6CB24",
"a$ c #CB9865",
"b$ c #69687A",
"c$ c #261C13",
"d$ c #1E170F",
"e$ c #6F5438",
"f$ c #AC8156",
"g$ c #887815",
"h$ c #C5AE1F",
"i$ c #786A13",
"j$ c #A8941A",
"k$ c #D3BA21",
"l$ c #80654B",
"m$ c #746612",
"n$ c #3C2D1E",
"o$ c #080604",
"p$ c #756712",
"q$ c #827314",
"r$ c #533E2A",
"s$ c #473E0B",
"t$ c #747284",
"u$ c #C29264",
"v$ c #17110C",
"w$ c #737284",
"x$ c #030201",
"y$ c #BE8F5F",
"z$ c #76593B",
"A$ c #956F4A",
"B$ c #D5BC21",
"C$ c #BD8E5E",
"D$ c #886644",
"E$ c #AF8458",
"F$ c #B4875A",
"G$ c #060403",
"H$ c #BAA31D",
"I$ c #A77E54",
"J$ c #9F774F",
"K$ c #211910",
"L$ c #C3AC1E",
"M$ c #8F6B47",
"N$ c #463423",
"O$ c #282306",
"P$ c #C19160",
"Q$ c #0A0705",
"R$ c #6A4F35",
"S$ c #795B3C",
"T$ c #E8CC24",
"U$ c #736D83",
"V$ c #5E472F",
"W$ c #AE8257",
"X$ c #B6A11C",
"Y$ c #302418",
"Z$ c #35281A",
"`$ c #C39262",
" % c #100C08",
".% c #897815",
"+% c #2C2116",
"@% c #544A0D",
"#% c #5F4730",
"$% c #1A1704",
"%% c #846342",
"&% c #5D462E",
"*% c #906C48",
"=% c #A17950",
"-% c #B6895B",
";% c #C4966A",
">% c #FCE65F",
",% c #090904",
"'% c #B98B5C",
")% c #97714C",
"!% c #7B7132",
"~% c #A39DB2",
"{% c #9C9DAC",
"]% c #9D9CB5",
"^% c #9C99AC",
"/% c #9495AC",
"(% c #9B99A4",
"_% c #9493A3",
":% c #9C93A4",
"<% c #938DA4",
"[% c #92909D",
"}% c #8B919C",
"|% c #47494E",
"1% c #1C1C1E",
"2% c #2A2A2E",
"3% c #48474E",
"4% c #605E69",
"5% c #67656D",
"6% c #716E7B",
"7% c #838694",
"8% c #8C859C",
"9% c #A39CB1",
"0% c #A3A1B8",
"a% c #9C9DB4",
"b% c #9494AC",
"c% c #9B99A5",
"d% c #9C94A4",
"e% c #9390A2",
"f% c #8C899C",
"g% c #837D93",
"h% c #9B9DAB",
"i% c #9B9DAC",
"j% c #211512",
"k% c #662D22",
"l% c #38201A",
"m% c #7B7D8C",
"n% c #8B8899",
"o% c #EE2924",
"p% c #A43426",
"q% c #8B91A3",
"r% c #928F9C",
"s% c #9D9AAA",
"t% c #57565A",
"u% c #202021",
"v% c #6D6A78",
"w% c #8C8EA5",
"x% c #7B778A",
"y% c #62626B",
"z% c #111011",
"A% c #414049",
"B% c #5B5979",
"C% c #616084",
"D% c #3A3A40",
"E% c #55555A",
"F% c #212123",
"G% c #0D0E0E",
"H% c #252629",
"I% c #060707",
"J% c #313133",
"K% c #46464A",
"L% c #5B5A62",
"M% c #7675AA",
"N% c #7D7DBC",
"O% c #313034",
"P% c #6A6973",
"Q% c #CE2F25",
"R% c #272727",
"S% c #36363A",
"T% c #3B3A41",
"U% c #6B6994",
"V% c #484955",
"W% c #B9B7B7",
"X% c #CCCACA",
"Y% c #858282",
"Z% c #4D4B4B",
"`% c #515069",
" & c #7A7AB3",
".& c #8180BD",
"+& c #7F7EBC",
"@& c #65638A",
"#& c #6C6A6D",
"$& c #2C2C2F",
"%& c #2D2F32",
"&& c #433F3C",
"*& c #454549",
"=& c #6A6B7A",
"-& c #DAD8D8",
";& c #D1D0CF",
">& c #B2B0AF",
",& c #898686",
"'& c #515053",
")& c #4E4C4D",
"!& c #706E9D",
"~& c #A6A4A3",
"{& c #4D4B63",
"]& c #E0DEEA",
"^& c #BBB9B8",
"/& c #959293",
"(& c #7C768B",
"_& c #737483",
":& c #EAE9E9",
"<& c #C6C4C4",
"[& c #1C1C1D",
"}& c #3E4145",
"|& c #908D8D",
"1& c #807D80",
"2& c #4F4F55",
"3& c #6D6E7A",
"4& c #4C5056",
"5& c #404048",
"6& c #363535",
"7& c #54526D",
"8& c #4C4B62",
"9& c #131312",
"0& c #5A5C69",
"a& c #676464",
"b& c #757274",
"c& c #484855",
"d& c #686791",
"e& c #110D0B",
"f& c #9E9B9B",
"g& c #7B7584",
"h& c #736E83",
"i& c #9390A5",
"j& c #7170A0",
"k& c #6A6879",
"l& c #351A13",
"m& c #883024",
"n& c #53251D",
"o& c #AA3125",
"p& c #ACA9A9",
"q& c #959393",
"r& c #312B24",
"s& c #DB2925",
"t& c #797684",
"u& c #28231E",
"v& c #BFBFE0",
"w& c #676773",
"x& c #737481",
"y& c #8F8C99",
"z& c #CECDE7",
"A& c #ACA9BB",
"B& c #B8B6CA",
"C& c #C7C7E2",
"D& c #C2C2E1",
"E& c #8B889B",
"F& c #817F8B",
"G& c #BCBACE",
"H& c #ADABC1",
"I& c #D7D6EB",
"J& c #BCBCDC",
"K& c #ACAAC6",
"L& c #D1D0E9",
"M& c #CFCEE8",
"N& c #59493B",
"O& c #3D342C",
"P& c #5B616A",
"Q& c #AE8665",
"R& c #322C26",
"S& c #907051",
"T& c #626573",
"U& c #C4C3D8",
"V& c #59493A",
"W& c #A07C5B",
"X& c #B58A61",
"Y& c #5A5D6A",
"Z& c #636674",
"`& c #D39D67",
" * c #63667B",
".* c #636A73",
"+* c #62697B",
"@* c #7F654B",
"#* c #DBA267",
"$* c #6B5643",
"%* c #443D38",
"&* c #6B6E7C",
"** c #6A6D7B",
"=* c #6B6A7B",
"-* c #6A697B",
";* c #626173",
">* c #636274",
",* c #8F6F51",
"'* c #737182",
")* c #715A46",
"!* c #5B6174",
"~* c #525E62",
" ",
" ",
" ",
" ",
" . + @ # . @ . @ @ @ @ @ @ $ % & $ * $ * & = = = - ; > ; , > , > ' , ' ' ' ) ! ) ~ ! ~ ! ~ { ~ ] ] ^ ] / ^ ( / ( . + @ # . @ . @ @ @ @ @ @ $ % & $ * $ * & = = = - ; > ; , > , > ' , ' ' ' ) ! ) ~ ! ~ ! ~ { ~ ] ] ^ ] / ^ ( / ( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" + @ . . @ @ @ @ @ @ @ @ $ % $ : < & = & - - = = ; > ; > [ , , ' , } ' ' ) ! ) ! ~ ~ ~ ~ { ~ ] ] ^ ] / ] / / / / + @ . . @ @ @ @ @ @ @ @ $ % $ : < & = & - - = = ; > ; > [ , , ' , } ' ' ) ! ) ! ~ ~ ~ ~ { ~ ] ] ^ ] / ] / / / / _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" @ . @ # @ . @ @ @ @ @ $ % $ * & & : & = - = | 1 > ; > , 2 > ' , ' ' ) ' ! ) ! ~ ~ ! 3 { ~ ] ^ ] ] / ] / / ( / 4 @ . @ # @ . @ @ @ @ @ $ % $ * & & : & = - = | 1 > ; > , 2 > ' , ' ' ) ' ! ) ! ~ ~ ! 3 { ~ ] ^ ] ] / ] / / ( / 4 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" # . # . @ @ @ @ @ @ $ & 5 6 7 8 8 8 9 6 0 , 1 a ; > , , [ ' 2 ' ' ' ' ~ ) ! 3 ~ ~ ~ ] ~ ] ] ] ^ / ] / / / / b / # . # . @ @ @ @ @ @ $ & 5 6 7 8 8 8 9 6 0 , 1 a ; > , , [ ' 2 ' ' ' ' ~ ) ! 3 ~ ~ ~ ] ~ ] ] ] ^ / ] / / / / b / _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" . @ @ @ @ @ @ @ @ & : c d 8 e f f f g 8 8 8 9 6 h ~ ) 5 ' , ' ' ' ) ! ) ! ~ ~ ~ ~ { ~ { ] ^ ] / ] / / / / b / b . @ @ @ @ @ @ @ @ & : c d 8 e f f f g 8 8 8 9 6 h ~ ) 5 ' , ' ' ' ) ! ) ! ~ ~ ~ ~ { ~ { ] ^ ] / ] / / / / b / b _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" @ @ . @ @ @ @ @ & * i 8 j k l l l l l m n 8 8 o p q 9 6 h 4 { r ) ! ) ! ~ ~ ~ 3 ] ~ ] ] ^ ] / { / / / / b / b b @ @ . @ @ @ @ @ & * i 8 j k l l l l l m n 8 8 o p q 9 6 h 4 { r ) ! ) ! ~ ~ ~ 3 ] ~ ] ] ^ ] / { / / / / b / b b _ _ _ _ _ _ _ _ _ _ _ _ _ s t u v w x y z A _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" . @ @ @ @ @ @ & @ B d e C l l l l l l l D g 7 E m F g 7 G q 9 H I J 4 ^ ~ ~ ~ { ~ ] ] ^ ] / ] / / / / b / b 4 K . @ @ @ @ @ @ & @ B d e C l l l l l l l D g 7 E m F g 7 G q 9 H I J 4 ^ ~ ~ ~ { ~ ] ] ^ ] / ] / / / / b / b 4 K _ _ _ _ _ _ _ _ _ _ _ L M N O P Q R S N N T U V z _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" @ @ @ @ @ @ < @ , n 9 W l l l l l l l l l k 7 9 C l l D X c g Y G d 9 6 I Z ` ^ { ] ] ] / ] / / / / b / b b 4 b @ @ @ @ @ @ < @ , n 9 W l l l l l l l l l k 7 9 C l l D X c g Y G d 9 6 I Z ` ^ { ] ] ] / ] / / / / b / b b 4 b _ _ _ _ _ _ _ _ _ _ ...+.@.l l l l l #.$.N N N N %.&.*.=._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" @ @ @ @ @ < @ & F 8 -.l l l l l l l l l l l X 8 c l l l l l l k X F j 9 G p 9 6 F h J / { / / / / b / b b b K K @ @ @ @ @ < @ & F 8 -.l l l l l l l l l l l X 8 c l l l l l l k X F j 9 G p 9 6 F h J / { / / / / b / b b b K K _ _ _ _ _ _ _ _ _ _ ;.>.,.l l l l l l l '.$.).!.~.R {.N ].^.&.*./._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" @ @ @ @ & @ & (._.9 :.l l l l l l l l l l l C 6 7 k l l l l l l l l l W E F _.9 G p 9 6 c <.0 / b / b b b K b [. @ @ @ @ & @ & (._.9 :.l l l l l l l l l l l C 6 7 k l l l l l l l l l W E F _.9 G p 9 6 c <.0 / b / b b b K b [. _ _ _ _ _ _ _ _ _ }.|.1.l l l l l l l l l 2.{.3.4.l 5.6.~.7.8.N 9.0.&.a.b._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" @ @ @ $ @ < : c.Y c C l l l l l l l l l l l l X 8 d.l l l l l l l l l l l l l :.-.c _.n o p 9 H c e.h b K b f.K @ @ @ $ @ < : c.Y c C l l l l l l l l l l l l X 8 d.l l l l l l l l l l l l l :.-.c _.n o p 9 H c e.h b K b f.K _ _ _ _ _ _ _ _ _ &.g.h.l l l l l l l l l l i.+.j.l l l l l 4.6.k.7.l.N m.0.n.o.p._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" @ @ $ % < : & < q q.l l l l l l l l l l l l l W 9 6 r.l l l l l l l l l l l l l l l l :.-.F 6 n G q 7 6 ` f.b f. @ @ $ % < : & < q q.l l l l l l l l l l l l l W 9 6 r.l l l l l l l l l l l l l l l l :.-.F 6 n G q 7 6 ` f.b f. _ _ _ _ _ _ _ _ s.t.u.l l l l l l l l l l l l v.w.x.l l l l l l l l l y.z.A.B.>.C.D.E.y F.A _ _ _ _ _ _ _ _ _ _ ",
" @ $ % $ : & & G.p X l l l l l l l l l l l l l H.c Y W l l l l l l l l l l l l l l l l l l l r.I.X d.6 8 _.` f.f. @ $ % $ : & & G.p X l l l l l l l l l l l l l H.c Y W l l l l l l l l l l l l l l l l l l l r.I.X d.6 8 _.` f.f. _ _ _ _ _ _ _ _ J.N K.l l l l l l l l l l l l L.N M.l l l l l l l l l l l l l N.z.A.S >.N T E.y O.L _ _ _ _ _ _ ",
" $ % $ * & & - P.Y m l l l l l l l l l l l l l l E p X l l l l l l l l l l l l l l l l l l l l l l l D c 8 6 f.f. $ % $ * & & - P.Y m l l l l l l l l l l l l l l E p X l l l l l l l l l l l l l l l l l l l l l l l D c 8 6 f.f. _ _ _ _ _ _ _ _ Q.R.h.l l l l l l l l l l l l S.T.U.l l l l l l l l l l l l l l l l l N.z.R S N N V.W._ _ _ _ _ ",
" % $ * $ < $ & I g :.l l l l l l l l l l l l l l m G B l l l l l l l l l l l l l l l l l l l l l l l l C e p h f. % $ * $ < $ & I g :.l l l l l l l l l l l l l l m G B l l l l l l l l l l l l l l l l l l l l l l l l C e p h f. _ _ _ _ _ _ _ _ X.Y.l l l l l l l l l l l l l l Z.w.l l l l l l l l l l l l l l l l l l l l l `. +.+N ++_ _ _ _ ",
" & : & < - & - @+g :.l l l l l l l l l l l l l l :.7 c l l l l l l l l l l l l l l l l l l l l l l l l l :.d H #+ & : & < - & - @+g :.l l l l l l l l l l l l l l :.7 c l l l l l l l l l l l l l l l l l l l l l l l l l :.d H #+ _ _ _ _ _ _ _ _ X.$+l l l l l l l l l l l l l l %+&+*+l l l l l l l l l l l l l l l l l l l l l l =+-+C.;+_ _ _ ",
" $ & & >+& - = I g :.l l l l l l l l l l l l l l k j _.H.l l l l l l l l l l l l l l l l l l l l l l l l l _.p f. $ & & >+& - = I g :.l l l l l l l l l l l l l l k j _.H.l l l l l l l l l l l l l l l l l l l l l l l l l _.p f. _ _ _ _ _ _ _ _ ,+'+l l l l l l l l l l l l l l *+N i.l l l l l l l l l l l l l l l l l l l l l l l x.)+!+~+_ _ ",
" * & : & = = - @+g :.l l l l l l l l l l l l l l C 6 j D l l l l l l l l l l l l l l l l l l l l l l l l l -.q F * & : & = = - @+g :.l l l l l l l l l l l l l l C 6 j D l l l l l l l l l l l l l l l l l l l l l l l l l -.q F _ _ _ _ _ _ _ _ |.'+l l l l l l l l l l l l l l {+]+^+l l l l l l l l l l l l l l l l l l l l l l l l K.>.;+_ _ ",
" $ - & = = - - @+g :.l l l l l l l l l l l l l l C 6 j r.q.i E W l l l l l l l l l l l l l l l l l l l l l k q H $ - & = = - - @+g :.l l l l l l l l l l l l l l C 6 j r.q.i E W l l l l l l l l l l l l l l l l l l l l l k q H _ _ _ _ _ _ _ _ |.'+l l l l l l l l l l l l l l l Y./+l l l l l l l l l l l l l l l l l l l l l l l l l (+_+_ _ ",
" * & - = - 1 | @+g :.l l l l l l l l l l l l l l r.c :+:.6 8 8 p p H B <+k l l l l l l l l l l l l l l l l r.G n * & - = - 1 | @+g :.l l l l l l l l l l l l l l r.c :+:.6 8 8 p p H B <+k l l l l l l l l l l l l l l l l r.G n _ _ _ _ _ _ _ _ |.'+l l l l l l l l l l l l l l l [+}+l |+l l l l l l l l l l l l l l l l l l l l l l l 1+2+3+_ ",
" < = = = - | 1 4+Y m l l l l l l l l l l l l l l l f Y q.Y 5+6+7+5+8+8 8 q 7 6 q.I.9+l l l l l l l l l l l l j 9 < = = = - | 1 4+Y m l l l l l l l l l l l l l l l f Y q.Y 5+6+7+5+8+8 8 q 7 6 q.I.9+l l l l l l l l l l l l j 9 _ _ _ _ _ _ _ _ |.'+l l l l l l l l l l l l l l l '+}+l 8.0+$+a+b+l l l l l l l l l l l l l l l l l l l c+N d+_ ",
" - = - = ; > ; e+q E l l l l l l l l l l l l l l l f Y c p 8 d f+g+6+h+7+g+f+8+8 8 8 Y 6 -.W l l l l l l l l c q - = - = ; > ; e+q E l l l l l l l l l l l l l l l f Y c p 8 d f+g+6+h+7+g+f+8+8 8 8 Y 6 -.W l l l l l l l l c q _ _ _ _ _ _ _ _ X.'+l l l l l l l l l l l l l l l '+}+i+N j+k+N N N l+m+n+o+l l l l l l l l l l l l l l '.p+Q._ ",
" = = | 1 > ; > [ p q.l l l l l l l l l l l l l l l f G :.k q.6 q 8 8 o f+7+6+h+h+7+5+8+d 8 8 d g i E k r.l l f 8 = = | 1 > ; > [ p q.l l l l l l l l l l l l l l l f G :.k q.6 q 8 8 o f+7+6+h+h+7+5+8+d 8 8 d g i E k r.l l f 8 _ _ _ _ _ _ _ _ X.q+l l l l l l l l l l l l l l l '+r+s+N t+u+v+w+x+y+z+A+B+C+P D+E+F+=+l l l l l l l l l Y.Q._ ",
" - - 1 | ; > 2 2 9 i C l l l l l l l l l l l l l l q.o X l l l l W q.6 d 8 8 8+5+7+6+h+h+6+7+5+8+q 8 _.k l l f 8 - - 1 | ; > 2 2 9 i C l l l l l l l l l l l l l l q.o X l l l l W q.6 d 8 8 8+5+7+6+h+h+6+7+5+8+q 8 _.k l l f 8 _ _ _ _ _ _ _ _ G+8.4.l l l l l l l l l l l l l l '+C+H+I+J+N K+L+M+N+O+P+Q+R+S+T+N N U+V+W+X+6.l l l l l Y.Y+_ ",
" = ; > ; > 2 , , n e k l l l l l l l l l l l l l l X 7 E l l l l l l l l :.d.e q q 8 8+5+7+h+Z+Z+Z+8+_.k l l f 8 = ; > ; > 2 , , n e k l l l l l l l l l l l l l l X 7 E l l l l l l l l :.d.e q q 8 8+5+7+h+Z+Z+Z+8+_.k l l f 8 _ _ _ _ _ _ _ _ *.N `+l l l l l l l l l l l l l l @C+l l r.y..@A.S N +@@@#@N+$@%@&@*@=@-@;@N B+l.>@l l l ,@X._ ",
" ; > ; > , 2 , ' H 9 :.l l l l l l l l l l l l l l X 7 -.l l l l l l l l l l l r.<+F n q 8 g+Z+h+Z+8+e k l l f 8 ; > ; > , 2 , ' H 9 :.l l l l l l l l l l l l l l X 7 -.l l l l l l l l l l l r.<+F n q 8 g+Z+h+Z+8+e k l l f 8 _ _ _ _ _ _ _ _ s C.'@l l l l l l l l l l l l l l '@C+l l l l l l )@y.!@~@]++.{@j+#@N+]@^@/@(@_@:@<@l l l '+X._ ",
" > ; > , , , ' , i p m l l l l l l l l l l l l l l I.G F l l l l l l l l l l l l l l l m o g+Z+h+h+8+c C l l f 8 > ; > , , , ' , i p m l l l l l l l l l l l l l l I.G F l l l l l l l l l l l l l l l m o g+Z+h+h+8+c C l l f 8 _ _ _ _ _ _ _ _ _ [@}@l l l l l l l l l l l l l l '@+.|@l l l l l l l l l l 1@a+2@C+N 3@4@^@^@^@j+5@l l l '+X._ ",
" ; > [ , [ ' , ' I q E l l l l l l l l l l l l l l :.9 c r.l l l l l l l l l l l l l l I.Y 5+Z+Z+6+o B 9+l l f 8 ; > [ , [ ' , ' I q E l l l l l l l l l l l l l l :.9 c r.l l l l l l l l l l l l l l I.Y 5+Z+Z+6+o B 9+l l f 8 _ _ _ _ _ _ _ _ _ 6@7@l l l l l l l l l l l l l l `.N 8@l l l l l l l l l l l l l l 8@9@0@^@^@^@j+5@l l l '+X._ ",
" [ [ , , ' , ' ' 0 G f r.l l l l l l l l l l l l l r.6 j C l l l l l l l l l l l l l l W n 8+7+6+6+8+B H.l l f 8 [ [ , , ' , ' ' 0 G f r.l l l l l l l l l l l l l r.6 j C l l l l l l l l l l l l l l W n 8+7+6+6+8+B H.l l f 8 _ _ _ _ _ _ _ _ _ a@l.l l l l l l l l l l l l l l b@N c@l l l l l l l l l l l l l l l C+d@^@^@e@f@5@l l l Y.X._ ",
" > , > ' , ' } ' 3 9 i D l l l l l l l l l l l 9+W <+g q B <+:.C l l l l l l l l l l l k c p q 8+f+8 B 9+l l i p > , > ' , ' } ' 3 9 i D l l l l l l l l l l l 9+W <+g q B <+:.C l l l l l l l l l l l k c p q 8+f+8 B 9+l l i p _ _ _ _ _ _ _ _ _ g@h@i@l l l l l l l l l l l l l 5.{.j@l l l l l l l l l l l l l l l k@-@l@^@m@N 5@l l l Y.X._ ",
" [ , ' , ' ' ' ' ~ j g W l l l l l l l l k m -.c g 8 q Y q q 9 n@d.<+:.9+l l l l l l l l C m d.6 9 8 E r.l l _.Y [ , ' , ' ' ' ' ~ j g W l l l l l l l l k m -.c g 8 q Y q q 9 n@d.<+:.9+l l l l l l l l C m d.6 9 8 E r.l l _.Y _ _ _ _ _ _ _ _ _ o@N y.l l l l l l l l l l l l l '.[+p@q@r@l l l l l l l l l l l l l s@N t@@@u@N v@l l l Y.w@_ ",
" > ' 2 ' ' ' ) ! ) 6 7 I.l l l l r.:.E I j o 8 q g i #+= r e.e 9 q q 9 6 f <+k l l l l l l l l l k -.k l l l j 9 > ' 2 ' ' ' ) ! ) 6 7 I.l l l l r.:.E I j o 8 q g i #+= r e.e 9 q q 9 6 f <+k l l l l l l l l l k -.k l l l j 9 _ _ _ _ _ _ _ _ _ x@y@z@l l l l l l l l l h.K.u.A@).N B@N R.C@D@q@E@l l l l l l l l l r.y.D@C@R.N F@l l l Y.Q._ ",
" ' , ' ' ' ) ! ) ! c 8 I.l k <+B 6 :+8 8 Y 6 B ! G@H@H@H@H@I@H@G@>+h 6 9 q q n n@d.<+D l l l l l l l l l l l G g ' , ' ' ' ) ! ) ! c 8 I.l k <+B 6 :+8 8 Y 6 B ! G@H@H@H@H@I@H@G@>+h 6 9 q q n n@d.<+D l l l l l l l l l l l G g _ _ _ _ _ _ _ _ _ _ J@D+l l l l l |+K@L@M@R.N N@O@P@Q@R@S@T@U@V@N W@C@D@X@r@l l l l l l l l l r@Y@Z@l l 2.&+Q._ ",
" 2 ' } } ) ! ) ! ~ h p i c j Y 8 o _.c ` >+`@I@H@H@`@`@`@`@H@I@' F >+`@G@r I e Y o G n n@d.m D l l l l l l 9+q _. 2 ' } } ) ! ) ! ~ h p i c j Y 8 o _.c ` >+`@I@H@H@`@`@`@`@H@I@' F >+`@G@r I e Y o G n n@d.m D l l l l l l 9+q _. _ _ _ _ _ _ _ _ _ _ #.#l l 2.+#'+@#N N ##$#%#&#*#*#*#*#*#*#*#=#-#;#>#,#N '#C@)#X@|+l l l l l l l l l l `+N o@_ ",
" ' ' ) ' ! ) ! ~ ~ K 7 8 8 8 8 n c { G@I@I@I@I@H@H@H@`@`@I@`@e.G 8 G n I G@H@`@@ ( B H 9 p o 9 6 f m H.l l k d 6 ' ' ) ' ! ) ! ~ ~ K 7 8 8 8 8 n c { G@I@I@I@I@H@H@H@`@`@I@`@e.G 8 G n I G@H@`@@ ( B H 9 p o 9 6 f m H.l l k d 6 _ _ _ _ _ _ _ _ _ _ !#C+/+q+N N N ~#{#Q@*#*#*#*#*#*#*#*#*#*#*#]#^#/#*#/#-#{#>#N N O )+)#X@l l l l l l l (#N d+_ ",
" ' ' ' ~ ) ! 3 3 ~ _#F n@g n G G Y 9 n j _.e.B { $ `@I@I@r g 8 :#8 <#:+q 9 `@`@H@H@H@G@# r h e Y 8 d 9 6 d.B q c ' ' ' ~ ) ! 3 3 ~ _#F n@g n G G Y 9 n j _.e.B { $ `@I@I@r g 8 :#8 <#:+q 9 `@`@H@H@H@G@# r h e Y 8 d 9 6 d.B q c _ _ _ _ _ _ _ _ _ _ [#N N N N }#%#|#1#*#*#*#*#*#*#*#*#*#*#2#3#N N +.4#5#*#*#*#6#7#{#8#+.N 9@9#0#1@l l l %+a#b#_ ",
" ' ) ! ) ! ~ ~ ~ ~ { ~ ( ` c#d#I I n@H 9 Y G p 7 Y 9 n 6 9 o e#f#G g#h#g#8 @ H@`@`@`@H@H@H@H@`@G@: <.9 8 p p 8 i# ' ) ! ) ! ~ ~ ~ ~ { ~ ( ` c#d#I I n@H 9 Y G p 7 Y 9 n 6 9 o e#f#G g#h#g#8 @ H@`@`@`@H@H@H@H@`@G@: <.9 8 p p 8 i# _ _ _ _ _ _ _ _ _ _ j#k#x l#v a#N N N@V@m#$#n#o#p#q#*#*#r#N@s#t#u#v#w#+.x#*#*#*#*#*#*#y#z#A#B#N +.]+9#!@C#[@_ _ ",
" ) ! ) ! ~ ~ ~ ~ ] ~ ] ] ] ] / { / / K Z d#D#B e.i _.n 9 8 :#f#E#7 F#G#f#8 c + I@I@I@I@I@H@- ` c j Y p 8 8 G g H# ) ! ) ! ~ ~ ~ ~ ] ~ ] ] ] ] / { / / K Z d#D#B e.i _.n 9 8 :#f#E#7 F#G#f#8 c + I@I@I@I@I@H@- ` c j Y p 8 8 G g H# _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ I#J#K#o.E.L#D.M#N N N#O#P#Q#R#S#T#N U#V#W#X#*#*#*#*#*#*#*#*#*#Y#Z#`# $N N N .$_ _ ",
" ! ) ! ~ ~ ~ 3 ] ~ ] { ] ^ / ] / / / / b / 4 b b K Z 0 c#g :+h#E#:#:#+$@$G q G 7 Y 6 H n G G p p Y n H i e.F i#<. ! ) ! ~ ~ ~ 3 ] ~ ] { ] ^ / ] / / / / b / 4 b b K Z 0 c#g :+h#E#:#:#+$@$G q G 7 Y 6 H n G G p p Y n H i e.F i#<. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ b##$$$[#%$&$*$=$-$;$N >$-$,$}#'$)$!$*#*#~${$]$^$/$($_$N t.0.&$:$_ _ ",
" ) ! ~ ~ ~ ~ ] ~ ] ] ] ^ ( ] / / / / b / b b b K b ` <$f.6 G [$E#F#:++$@$:#8 i g n 7 G 9 j 6 e.I i#<.}$H#<.<.<.<. ) ! ~ ~ ~ ~ ] ~ ] ] ] ^ ( ] / / / / b / b b b K b ` <$f.6 G [$E#F#:++$@$:#8 i g n 7 G 9 j 6 e.I i#<.}$H#<.<.<.<. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |$1$-$2$3$4$-$5$N N N +.6$6$}#N 7$[@X.8$g@9$0$_ _ _ _ _ ",
" 3 ~ ~ ~ ~ ] ~ { ] ] ^ ( ^ / / / / b / b b b K b f.<$f.f.6 7 [$E#g#q f#a$e#8 H#D#D#D#D#}$d#H#b$H#d#<.H#<.<.<.<.<. 3 ~ ~ ~ ~ ] ~ { ] ] ^ ( ^ / / / / b / b b b K b f.<$f.f.6 7 [$E#g#q f#a$e#8 H#D#D#D#D#}$d#H#b$H#d#<.H#<.<.<.<.<. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |$c$-$-$d$e$-$f$3$g$h$Q.i$X.Q.j$k$_ _ _ _ _ _ _ _ _ _ _ ",
" ! ~ ! ~ { ~ ] ] ] ^ ( ^ ( / ( / b / b 4 4 K b f.b f.` f.6 G [$E#l$8 f#@$[$8 i d#d#d#d#d#H#d#H#d#<.H#}$<.<.<.<.<. ! ~ ! ~ { ~ ] ] ] ^ ( ^ ( / ( / b / b 4 4 K b f.b f.` f.6 G [$E#l$8 f#@$[$8 i d#d#d#d#d#H#d#H#d#<.H#}$<.<.<.<.<. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ m$c$-$-$d$n$-$-$o$p$_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ~ ~ ~ { ~ ] ] { ^ ( ^ ( / / / b / 4 b b K 4 f.b f.f.f.f.6 G [$E#l$8 [$G#a$8 _.d#d#d#d#H#d#H#d#<.H#<.<.<.<.<.<.i# ~ ~ ~ { ~ ] ] { ^ ( ^ ( / / / b / 4 b b K 4 f.b f.f.f.f.6 G [$E#l$8 [$G#a$8 _.d#d#d#d#H#d#H#d#<.H#<.<.<.<.<.<.i# _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ q$c$-$-$r$n$-$-$n$s$_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ! ~ ] ~ ] { ^ { / { / / / / b / 4 b K b K [.K f.f.f.f.t$n@q [$@$f#q l$u$a$:+9 d#d#d#H#d#H#d#<.H#<.H#<.<.<.<.I <. ! ~ ] ~ ] { ^ { / { / / / / b / 4 b K b K [.K f.f.f.f.t$n@q [$@$f#q l$u$a$:+9 d#d#d#H#d#H#d#<.H#<.H#<.<.<.<.I <. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ q$c$-$-$r$v$-$-$e$M#b#_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ~ ] ~ ] ] ^ ] / ] / / ( / b / b b K b K [.K f.[.f.f.w$f.e.q l$E#+$d g#G#a$g#8 b$d#H#d#H#d#<.H#<.<.<.<.<.<.I i#i# ~ ] ~ ] ] ^ ] / ] / / ( / b / b b K b K [.K f.[.f.f.w$f.e.q l$E#+$d g#G#a$g#8 b$d#H#d#H#d#<.H#<.<.<.<.<.<.I i#i# _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ q$x$y$-$z$o$-$-$A$N B$_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" { ~ { ] ^ ] / { / / / / b / b 4 K 4 K [.K f.f.f.f.#+f.w$c q l$@$E#G F#G#a$l$8 e.H#b$H#d#<.H#<.<.<.<.<.<.I i#I <. { ~ { ] ^ ] / { / / / / b / b 4 K 4 K [.K f.f.f.f.#+f.w$c q l$@$E#G F#G#a$l$8 e.H#b$H#d#<.H#<.<.<.<.<.<.I i#I <. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ q$N C$-$D$x$E$-$F$G$[#_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ~ ] ^ ] { / { / / / / b / b b K b K [.K f.f.f.f.#+f.w$c#c q l$@$E#7 <#u$a$f#8 H d#H#d#<.H#<.<.<.<.<.<.<.i#I i#i# ~ ] ^ ] { / { / / / / b / b b K b K [.K f.f.f.f.#+f.w$c#c q l$@$E#7 <#u$a$f#8 H d#H#d#<.H#<.<.<.<.<.<.<.i#I i#i# _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ H$N C$-$I$N J$-$-$K$;._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ] ] ] ^ / ] / / / / 4 / b b K b K [.K f.f.f.f.w$f.#+c#w$e.q l$@$E#F#Y u$a$G#d n H#d#<.H#<.<.<.<.<.<.<.i#I i#I e. ] ] ] ^ / ] / / / / 4 / b b K b K [.K f.f.f.f.w$f.#+c#w$e.q l$@$E#F#Y u$a$G#d n H#d#<.H#<.<.<.<.<.<.<.i#I i#I e. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ L$N C$-$C$N M$-$-$N$O$_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ] ^ { / ] / / / / b / b b K b K [.K f.f.f.f.w$f.w$c#w$c#<.G g#G#E#F#o +$a$G#:#7 d#<.H#<.<.<.<.<.<.<.i#<.i#I e.i# ] ^ { / ] / / / / b / b b K b K [.K f.f.f.f.w$f.w$c#w$c#<.G g#G#E#F#o +$a$G#:#7 d#<.H#<.<.<.<.<.<.<.i#<.i#I e.i# _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ L$N C$-$P$Q$R$-$-$S$2+T$_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ^ ] / ] / / / / b / b b b b K [.K f.f.f.f.w$f.t$w$#+c#U$H#7 g#u$E#e#8 u$a$G#e#q i#H#<.H#<.<.<.<.<.i#<.i#I e.i#e. ^ ] / ] / / / / b / b b b b K [.K f.f.f.f.w$f.t$w$#+c#U$H#7 g#u$E#e#8 u$a$G#e#q i#H#<.H#<.<.<.<.<.i#<.i#I e.i#e. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ L$N T#-$-$c$V$-$-$W$N X$_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ] / ] / / / / b / b b 4 K K [.K f.f.f.f.#+f.w$w$c#c#U$c#}$7 g#u$E#l$8 h#a$G#[$8 i }$<.<.<.<.<.<.i#<.i#<.i#i#e.e. ] / ] / / / / b / b b 4 K K [.K f.f.f.f.#+f.w$w$c#c#U$c#}$7 g#u$E#l$8 h#a$G#[$8 i }$<.<.<.<.<.<.i#<.i#<.i#i#e.e. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ L$N D$-$-$Y$Z$-$-$`$ %.%_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" / ] / / / / b / b b b K b [.K f.f.f.f.w$f.#+#+c##+U$c#d#H#7 g#G#@$h#8 l$a$a$f#q _.<.<.<.<.<.<.i#<.i#<.e.i#e.e.e. / ] / / / / b / b b b K b [.K f.f.f.f.w$f.#+#+c##+U$c#d#H#7 g#G#@$h#8 l$a$a$f#q _.<.<.<.<.<.<.i#<.i#<.e.i#e.e.e. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ J#9.D$-$-$=$Z$-$-$-$+%@%_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ^ / / / / b / b b b K b f.K f.f.f.f.#+f.#+#+c#t$d#c#d#d#D#Y F#+$@$+$q e#a$a$+$:+Y <.<.<.<.I i#I i#I e.i#e.e.e.e. ^ / / / / b / b b b K b f.K f.f.f.f.#+f.#+#+c#t$d#c#d#d#D#Y F#+$@$+$q e#a$a$+$:+Y <.<.<.<.I i#I i#I e.i#e.e.e.e. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |.D$-$-$=$G$-$-$-$#%$%_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ( / ( / b / b b b K 4 f.b f.[.f.f.w$f.w$w$c##+d#t$d#U$d#d#9 <#f#@$E#d g#G#a$u$F#p i#<.<.I i#I i#I e.i#i#e.e.e.e. ( / ( / b / b b b K 4 f.b f.[.f.f.w$f.w$w$c##+d#t$d#U$d#d#9 <#f#@$E#d g#G#a$u$F#p i#<.<.I i#I i#I e.i#i#e.e.e.e. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |.D$-$-$D$N -$-$-$%%7$k$_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" / / / b / b b 4 K 4 f.b f.f.f.f.#+f.#+#+c#w$d#w$d#d#d#d#d#9 <#f#@$E#7 <#a$a$G#e#8 c <.I i#I i#I i#i#e.e.e.e.e.e. / / / b / b b 4 K 4 f.b f.f.f.f.#+f.#+#+c#w$d#w$d#d#d#d#d#9 <#f#@$E#7 <#a$a$G#e#8 c <.I i#I i#I i#i#e.e.e.e.e.e. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |.&%-$-$*%N =%-$-$-%B+j$_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ",
" ( / b / b b K b K [.K f.f.f.f.w$f.w$c#w$c#U$c#d#d#d#d#d#d#g <#f#;%;%:#:+u$u$u$h#8 i i#<.i#<.i#e.i#e.e.e.e.e.e.e. ( / b / b b K b K [.K f.f.f.f.w$f.w$c#w$c#U$c#d#d#d#d#d#d#g <#f#;%;%:#:+u$u$u$h#8 i i#<.i#<.i#e.i#e.e.e.e.e.e.e. >%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%,%r$-$-$'%N )%-$-$-$d$!%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%",
" ",
" ",
" ",
" ",
" ~%~%{%]%~%{%~%^%{%^%^%^%^%/%(%_%/%:%/%:%_%_%<%_%[%}%<%}%, <%|%1%2%2%3%3%4%5%6%) 7%8%~ 8%~ { ~ ] ] ^ ] / ^ ( / ( 9%0%@ a%9%@ 9%@ @ @ @ @ @ b%c%& b%d%b%d%& = = = e%}%> }%, > , > ' , ' f%' ) ! ) G.! ~ ! ~ { ~ ] ] ^ ] P.^ g%P.g% ",
" ~%{%~%~%h%{%^%i%^%^%^%^%/%(%/%: _%_%_%_%_%<%_%_%}%<%}%<%[ , |%j%k%k%l%l%N N N 8%7%~ ~ ~ { ~ ] ] ^ ] m%] / / / / 0%@ 9%9%@ @ @ @ @ @ @ @ b%c%b%(.< & = & e%e%= = }%> }%> [ , , f%, n%f%' ) ! ) ! G.~ ~ ~ { ~ ] ] ^ ] P.] P.P.P.P. ",
" {%~%h%]%i%~%{%^%^%^%^%/%(%/%:%_%_%: _%_%<%_%| [%<%}%<%, 2 <%3%l%o%o%o%o%o%p%N ~ ~ 8%7%{ ~ ] ^ ] ] m%] m%m%( / 4 @ 9%@ a%@ 9%@ @ @ @ @ b%c%b%d%& & (.& = e%= q%r%> }%> , 2 > ' , ' ' ) ' ! ) ! ~ ~ ! G.{ ~ ] ^ ] ] P.] P.P.g%P.P. ",
" ]%~%]%~%s%{%^%^%^%^%/%(%' t%u%N N N 2%|%v%_%[%| }%<%, , [ ' |%l%o%o%o%o%o%p%N 7%~ ~ ] ~ ] ] ] ^ m%] / / / / b / a%9%a%9%@ @ @ @ @ @ b%c%b%d%b%& b%< = e%e%= r%w%}%> , , [ ' 2 ' ' ' f%G.) ! G.G.~ ~ ] ~ ] ] ] ^ P.] P.P.P.P.x%P. ",
" ~%{%{%^%{%^%^%^%^%_%^%y%z%1%A%B%C%B%D%z%N N 2%|%v%, , [ f%, 3%l%o%o%o%o%o%k%z%~ 7%{ ~ { ] ^ ] m%] m%m%/ m%b / b 9%@ @ @ @ @ @ @ @ & @ , E%F%G%F%H%H%I%]+J%K%E%4+! , , [ f%, f%' ' ) ! ) ! ~ ~ ~ G.{ ~ { ] ^ ] P.] P.P.P.P.P.P.x% ",
" h%{%~%i%^%^%^%^%_%^%L%N D%M%N%N%N%N%N%M%O%N z%u%N N 2%3%P%' t%z%o%Q%p%p%p%k%R%7%] ~ ] ] ^ ] / { / m%m%m%b / b b @ @ 9%@ @ @ @ @ & @ e%S%N T%B%U%U%U%B%V%I%N I%]+H%T%E%6%, ' ' ' ) ! ) ! ~ ~ G.G.] ~ ] ] ^ ] P.{ P.P.P.P.x%P.P.x% ",
" ~%^%{%^%^%^%^%_%^%/ z%A%N%N%N%N%N%N%N%N%N%D%N W%X%Y%Z%u%N N u%N o%p%N N N N 2%{ ~ ] ] ^ ] / ] / / / m%b / b 4 K 9%@ @ @ @ @ @ & @ & T%N `% &.&+&+&+&+& &@&]+N #&@+$&G%G%F%S%E%H#! ) ! ~ ~ ~ ~ { ~ ] ] ^ ] P.] P.P.P.P.x%P.x%P.K ",
" ^%i%^%^%^%^%_%^%_%%&u%N%N%N%N%N%N%N%N%N%N%N%2%u%l l l l X%Y%&&N o%p%N *&y%7%] ~ { ] ] ] m%] m%m%/ m%b / b b 4 b @ @ @ @ @ @ < @ & =&N V%N%N%N%N%N%N%N%+&+&U%G%J%-&;&>&,&'&H%N I%]+J%)&=&~ ~ ] ~ { ] ] ] P.] P.P.P.P.x%P.P.x%P.x% ",
" h%^%^%^%^%_%s%_%] N B%N%N%N%N%N%N%N%N%N%N%N%!&N Y%l l l l l ~&N o%p%N 2%N N 2%*&y%] ^ / { m%m%/ m%b m%b b b K K @ @ @ @ @ < @ & (.H%]+ &N%N%N%N%N%N%N%N%N%+&{&N ,&l l {+]&;&^&,&)&F%N N ]+J%'&=&] ] ^ P.] P.P.P.P.x%P.x%P.x%K K ",
" ^%^%^%^%_%^%_%^%Z%1%N%N%N%N%N%N%N%N%N%N%N%N%N%D%1%l l l l l ~&N o%p%N l D /&t%2%N N 2%*&4%/ / / b m%b b b K b (& @ @ @ @ & @ & (._&I%{&N%N%N%N%N%N%N%N%N%N%N% &H%]+{+l l l l l {+:&-&<&,&)&[&N I%G%S%'&_&P.P.P.P.x%P.P.x%x%K x%x% ",
" ^%6%[%/%^%_%: _%2%A%N%N%N%N%N%N%N%N%N%N%N%N%N%!&N /&l l l l ~&N o%p%N l l l l l D /&t%2%N N R%}&4%v%b b K b f.K @ @ @ b%@ < (.c.K%N M%N%N%N%N%N%N%N%N%N%N%N%.&B%N |&l l l l l l l l l {+{+:&<&1&K%]+N N G%S%E%_&P.x%P.x%K x%_&K ",
" ^%R%N z%2%*&2&3&N B%N%N%N%N%N%N%N%N%N%N%N%N%N%N%u%Z%l l l l ~&N o%k%u%l l l l l l l l l D /&t%2%N N 1%4&b f.b f. @ @ b%c%< (.& < H%$& &N%N%N%N%N%N%N%N%N%N%N%N%+&]+K%l l l l l l l l l l l l l l l l -&,&)&[&N N ]+$&5&=&P._&x%_& ",
" ^%6&N N z%2%u%N N z%2%A%7&C%N%N%N%N%N%N%N%N%N%N%8&u%l l l l ~&N o%k%6&l l l l l l l l l l l l l l W%Z%N 6&b f.f. @ b%c%b%(.& & G.9&V% &N%N%N%N%N%N%N%N%N%N%N%N%+&K%I%{+l l l l l l l l l l l l l l l l l l l ;&1&)&H%G%G%0&x%_&_& ",
" /%Z%2%a&z%z%Z%W%~&b&t%6&z%N N 1%2%c&7&C%N%N%N%N%d&N X%l l l ~&N o%k%6&l l l l l l l l l l l l l l l l Y%N *&f.f. b%c%b%d%& & e%P.e&B% &N%N%N%N%N%N%N%N%N%N%N%N%+&@&N f&l l l l l l l l l l l l l l l l l l l l l l l ^&J%N 0&_&_& ",
" (%5%N l D Y%u%N Z%X%l l l D ~&b&t%6&N N N u%O%c&B%N /&l l l ~&N o%k%6&l l l l l l l l l l l l l l l l l a&z%3&f. c%b%d%b%< b%& I N @&N%N%N%N%N%N%N%N%N%N%N%N%N%+& &I%#&l l l l l l l l l l l l l l l l l l l l l l l l -&$&F%4+_& ",
" _%g&N W%l l l Y%u%N &&~&l l l l l l l X%~&a&Z%6&N N a&l l l ~&N o%k%6&l l l l l l l l l l l l l l l l l D z%}&#+ & (.& < e%& e%@+N M%N%N%N%N%N%N%N%N%N%N%N%N%N%N%.&[&K%l l l l l l l l l l l l l l l l l l l l l l l l l |&G%'&h& ",
" /%_%N /&l l l l l /&6&N 6&~&l l l l l l l l l l l a&t%l l l W%N Q%k%6&l l l l l l l l l l l l l l l l l l t%1%f. b%& & b%& e%i&I N j&N%N%N%N%N%N%N%N%N%N%N%N%N%N%.&J%$&l l l l l l l l l l l l l l l l l l l l l l l l l l $&[&_& ",
" :%_%R%a&l l l l l l l ~&6&N 2%Y%l l l l l l l l l /&6&l l l l N p%k%6&l l l l l l l l l l l l l l l l l l W%N 4% d%& (.< = = e%@+N j&N%N%N%N%N%N%N%N%N%N%N%N%N%N%.&5&I%l l l l l l l l l l l l l l l l l l l l l l l l l l d.I%k& ",
" /%<%6&&&l l l l l l l l l W%Z%N u%Y%l l l l l l W%Z%6&l l l l N p%k%6&l l l l l l l l l l l l l l l l l l l z%|% b%e%& = = e%= @+N j&N%N%N%N%N%N%N%N%N%N%N%N%N%N%.&{&N l <&|&<&:&l l l l l l l l l l l l l l l l l l l l l <&G%K% ",
" :%_%|%2%l l l l l l l l l l l X%Z%N u%b&X%/&Z%z%N z%6&l l l l N p%k%D%l l l l l l l l l l l l l l l l l l l 6&D% d%& e%= e%r%q%@+N j&N%N%N%N%N%N%N%N%N%N%N%N%N%N%+&V%I%l @+N H%T%'&#&f&<&{+l l l l l l l l l l l l l l l l l ]+J% ",
" _%_%v%N l l l l l l l l l l l l l X%t%z%N N 6&b&X%~&u%l l l l N p%l%a&l l l l l l l l l l l l l l l l l l l t%R% < = = = e%q%r%4+I%B%N%N%N%N%N%N%N%N%N%N%N%N%N%N%N%B%N <&J%l&m&n&l&]+G%[&J%K%I f&-&l l l l l l l l l l l l l S%H% ",
" [%_%4 N W%l l l l l l l l l l l l l l D ~&D l l l l N l l l l N p%l%a&l l l l l l l l l l l l l l l l l l l a&R% e%= e%= }%> }%e+9&{&N%N%N%N%N%N%N%N%N%N%N%N%N%N%+&@&N f&N N n&n&m&o&o&m&n&l&I%I%F%J%'&d.p&:&l l l l l l l l K%9& ",
" _%_%| N /&l l l l l l l l l l l l l l l l l l l l l N l l l l N l%z%a&l l l l l l l l l l l l l l l l l l l Y%z% = = q%r%> }%> [ ]+T% &N%N%N%N%N%N%N%N%N%N%N%N%N%+&@&N >&q&E%r&I%N l&l&m&m&o&s&o&m&n&[&G%I%[&J%'&1&^&l l l l #&I% ",
" <%_%[%2%a&l l l l l l l l l l l l l l l l l l l l l N l l l l a&a&a&~&l l l l l l l l l l l l l l l l l l l ~&N e%e%r%w%}%> 2 2 $&H% &N%N%N%N%N%N%N%N%N%N%N%N%N%+&@&N p&l :&;&<&q&E%H%N N e&n&m&o&s&s&s&o&n&l&9&N I%)&;&l l d.I% ",
" _%}%<%D%&&l l l l l l l l l l l l l l l l l l l l l z%~&l l l l l l l l l l l l l l l l l l l l l l l l l l ~&N = }%> }%> 2 , , K%I% &N%N%N%N%N%N%N%N%N%N%N%N%N%N% &N d.l l l l l :&-&;&q&'&F%N I%e&n&m&s&s&s&s&s&l&$&;&l l d.I% ",
" }%<%}%3%2%l l l l l l l l l l l l l l l l l l l l l 6&~&l l l l l l l l l l l l l l l l l l l l l l l l l l ~&N }%> }%> , 2 , ' E%N U%N%N%N%N%N%N%N%N%N%N%N%N%N%N%+&N d.l l l l l l l l {+{+:&-&,&)&[&N ]+o&s&s&s&l&T%;&l l d.I% ",
" <%}%<%P%N l l l l l l l l l l l l l l l l l l l l l 6&Y%l l l l l l l l l l l l l l l l l l l l l l l l l l ~&N > }%> , , , ' , t&I%B%N%N%N%N%N%N%N%N%N%N%N%N%N%N%+&]+)&l l l l l l l l l l l l l l l <&[&n&s&s&s&l&E%:&l l d.I% ",
" }%<%[ / N W%l l l l l l l l l l l l l l l l l l l l 6&a&l l l l l l l l l l l l l l l l l l l l l l l l l l ~&N }%> [ , [ ' , f%' 9&5&N%N%N%N%N%N%N%N%N%N%N%N%N%N%+&$&T%l l l l l l l l l l l l l l l -&u&n&s&s&s&l&E%:&l l d.I% ",
" [ [ , , N Y%l l l l l l l l l l D ~&~&~&~&a&a&a&a&&&1%&&l l l l l l l l l l l l l l l l l l l l l l l l l l a&1% [ [ , , ' , ' f%f%F%H%N%N%N%N%N%N%N%N%N%N%N%N%N%N%N%T%]+l l l l l l l l l l l l l l l -&u&n&s&s&s&l&E%:&l l #&I% ",
" <%, <%f%2%6&a&a&&&6&6&6&u%N N N N N N N N u%2%2%2%u%N z%b&W%l l l l l l l l l l l l l l l l l l l l l l l l a&R% > , > f%, f%n%' ' T%]+N%N%N%N%N%N%N%N%N%N%+&+&N%M%j&T%N f&<&-&:&l l l l l l l l l l l ]&'&I%e&l&n&I%#&{+l l '&G% ",
" [ , ' , 3%2%2%2%D%2%z%c&8&C%C%C%C%N%N%N%N%!&7&O%z%N N O%1%N z%&&b&W%l l l l l l l l l l l l l l l l l l l l a&R% [ , ' , ' f%f%' ~ @+N M%N%N%N%N%N%+&+&N% &j&@&`%S%]+N ]+N e&J%I q&^&;&{+l l l l l l l l -&f&@+J%[&N |&l l l 5&F% ",
" <%' 2 ' ' f%) 8%) 4%N N%N%N%N%N%N%M%B%A%1%N N D%5%1%O%v&*#]%v%A%1%N z%&&b&W%l l l l l l l l l l l l l l l l 6&O% > ' 2 ' ' f%) ! ) w&N B%+&+&+&.&N%j&@&`%5&F%I%G%$&I%I%x%P.)&$&]+N 9&J%@+|&>&;&l l l l l l l l l ;&d.^&l l l S%H% ",
" ' , ' ' ' ) 8%) 8%x&N d&N%N%d&c&2%N N R%2&y&z&z&A&N g&*#*#*#*#*#*#]%v%A%1%N z%&&b&W%l l l l l l l l l l l l 6&D% ' , ' ' ' ) ! ) ! t&N `%.& &@&B%5&H%I%I%F%S%I r%B&[&T%C&D&C&D&0%{ E%J%]+I%9&J%@+,&>&-&l l l l l l l l l l l ]+J% ",
" 2 f%E&E&) 8%) 8%~ ~ N D%O%z%N 1%*&F&G&z&z&z&z&z&*&1%*#*#*#*#*#<%t%<%*#*#*#]%v%A%1%N z%&&b&W%l l l l l l l l z%3% 2 f%n%' ) ! ) ! ~ ~ [&$&V%$&G%I%[&5&@+e+H&I&I&]&@+N a%J&J&J&D&0%w&i&J&H&g%E%T%[&I%e&J%E%1&p&]&l l l l l l :&9&T% ",
" ' ' ) ' 8%) 8%~ ~ / z%z%D%5%A&z&z&z&z&z&z&z&z&A&N v%*#*#*#*#t%N N N R%4%K&*#*#*#*#]%v%A%1%N z%&&b&W%l l l l N 4& ' ' ) ' ! ) ! ~ ~ G.F%N 9&T%@+1&9%C&I&I&L&M&M&C&[&J%D&J&J&D&=&F%N 9&T%k&0%D&J&(.x%@+T%[&I%e&J%'&d.p&:&l l -&9&K% ",
" ' ' ' ~ ) 8%7%7%~ D%z%G&z&z&z&z&z&z&z&z&z&z&z&*&1%*#*#*#<%R%z%N&z%N&O&z%z%*#*#*#*#*#*#*#*#]%4%D%z%N z%&&b&b&N P& ' ' ' ~ ) ! G.G.~ E%N @+c.B&L&I&L&L&z&z&z&z&I&#&N _&C&C&H&T%I%9&]+u&r&N H%a%J&J&D&D&H&b%x%@+T%]+N 9&J%)&1&#&I%E% ",
" ' ) 8%) 8%~ ~ 7%y%N 6%z&z&z&z&z&z&z&z&z&z&z&G&z%N N R%O%O%u%Q&a$R&N&a$S&N ]%*#*#*#*#*#*#*#*#*#*#*#<%A%N N N N T& ' ) ! ) ! ~ ~ ~ ^ ]+$&C&L&M&M&z&z&z&z&z&z&L&U&H%N H%S%T%5&N V&W&O&O&X&V&N G.D&J&J&J&J&J&D&D&J&0%i&I $&N e&9&N i# ",
" ) 8%) 8%~ ~ ~ ~ 2%O%z&z&z&z&z&z&z&z&z&z&z&z&L%z%Y&L%}&D%1%R&a$a$O&&&a$a$N t%]%*#*#*#*#*#*#<%v%2&%&z%N N 1%%&*&Z& ) ! ) ! ~ ~ ~ ~ 5&N c.M&z&z&z&z&z&z&z&z&z&I&6%G%5&5&$&F%G%[&X&`&O&O&`&X&]+E%(.C&C&D&C&C&D&b%t&I 5&H%9&N N 9&J%<. ",
" 8%) 8%~ ~ ~ 7%y%N y&z&z&z&z&z&z&z&z&z&z&z&G&z%A%K <$g&<$Z%z%a$a$N&R&a$a$R&N N N R%O%A%R%N N z%R%6&|%2& *.*P%T&Z& ! ) ! ~ ~ ~ G.6%9&T%U&z&z&z&z&z&z&z&z&z&M&I&J%[&=&_&6%4+5&[&W&`&V&[&W&`&r&I%]+F%$&K%K%J%F%]+9&G%F%$&T%`%0&@+i#<. ",
" ) 8%~ 7%7%~ ] 2%O%z&z&z&z&z&z&z&z&z&z&z&z&5%z%c#b g&<$f.L%N a$a$N&R%a$a$N&R%4%t%D%D%2%D%2&P&+*P%+*P% *.*T&T&T&T& ) ! ~ G.G.~ ] S%N H&z&z&z&z&z&z&z&z&z&z&I&t&9&E%x%t&<$_&<.9&@*#*$*]+W&#*%*G%K%T%$&F%]+F%T%V%0&I <.w&<.H#<.<.<.<. ",
" 7%~ 7%7%~ ] y%N y&z&z&z&z&z&z&z&z&z&z&z&z&1%6&b f.<$f.f.L%N a$a$S&N a$a$S&N &***&***&*=*&*.*-*.*=*T&.*T&T&T&T&;* G.~ G.G.~ ] _&9&E%U&z&z&z&z&z&z&z&z&z&M&L&S%[&6%_&<$_&_&w&9&@*#*@*e&@*#*$*e&0&=&=&=&=&k&=&H#k&H#=&<.H#<.<.<.<.<. ",
" 8%~ 8%~ { 7%6&O%z&z&z&z&z&z&z&z&z&z&z&z&6%N v%f.b f.g&f.L%N a$a$S&N Q&a$Q&N t%******=***.*=*.*=*T&.* *T&T&T&>*T& ! ~ ! ~ { G.5&N c%z&z&z&z&z&z&z&z&z&z&I&P.]+'&_&x%_&t&_&w&9&@*#*@*]+@*#*,*[&V%4+=&=&=&=&H#=&H#=&<.H#}$<.<.<.<.<. ",
" ~ ~ ~ { ~ '*N 6%z&z&z&z&z&z&z&z&z&z&z&z&1%6&f.b f.f.f.f.L%N a$a$a$N S&a$a$1%A%****-*&*.*=*.*=*T&.*T&T&T&T&;*Z&P& ~ ~ ~ { ~ g%F%5&B&M&z&z&z&z&z&z&z&z&M&z&5&9&H#x%_&_&_&_&w&9&@*#*,*e&$*#*G#u&S%=&=&k&4+H#=&H#=&<.H#<.<.<.<.<.<.i# ",
" 8%~ ] ~ ] Z%z%z&z&z&z&z&z&z&z&z&z&z&z&F&N v%K f.f.f.f.t$3&N S&a$a$N S&a$a$O&2%&*=***.*=*.*=*T&.*Z&Z&T&Z&;*Z&y%;* ! ~ ] ~ ] E%N e+M&z&z&z&z&z&z&z&z&z&I&e+]+K%K _&_&_&_&_&w&e&$*#*W&[&V&`&#*r&F%H#=&=&H#=&H#=&<.H#<.H#<.<.<.<.I <. ",
" ~ ] ~ ] ] u%*&z&z&z&z&z&z&z&z&z&z&z&z&O%R%K f.(&f.f.w$f.t$N S&a$a$R%N&a$a$)*z%-*&*.*=*.*=*T&.*T&T&T&T&;*T&y%!*P& ~ ] ~ ] P.S%F%H&M&z&z&z&z&z&z&z&z&L&C&K%9&H#_&x%_&_&_&_&k&[&V&#*X&r&%*G##*V&9&<.4+H#=&H#=&<.H#<.<.<.<.<.<.I i#i# ",
" { ~ { ] c#N s%z&z&z&z&z&z&z&z&z&z&z&6%N L%f.f.f.f.'*f.w$c#N S&a$a$R&N&a$a$S&N y%.*-*.*=*T&.*Z&T&T&T&;*Z&y%!*y%;* { ~ { ] )&]+@+U&z&z&z&z&z&z&z&z&z&I&e+9&K%_&_&_&_&_&_&_&<.[&V&#*G#O&O&X&#*,*9&0&H#=&H#=&<.H#<.<.<.<.<.<.I i#I <. ",
" ~ ] ^ ] Z%1%z&z&z&z&z&z&z&z&z&z&z&A&z%D%f.f.f.f.'*f.#+c#w$N S&a$a$N&R&a$a$a$N c&=*.*=*T&.*T&T&T&T&;*Z&>*!*y%!*P& ~ ] ^ { $&N n%L&z&z&z&z&z&z&z&z&I&H&$&9&w&_&_&_&_&_&_&4+k&]+V&#*G#%*u&W&`&X&]+5&k&H#=&<.H#<.<.<.<.<.<.<.i#I i#i# ",
" ] ] ] ^ %&D%z&z&z&z&z&z&z&z&z&z&G&R%u%&*f.f.f.w$f.#+c#w$c#N S&a$a$N&R&a$a$a$R%D%.*=*T&.*T&T&T&T&;*T&;*P&y%!*y%Y& ] ] ] ^ G%F%0%L&z&z&z&z&z&z&z&L&B&5&N E%_&_&_&_&_&_&4+_&H#[&V&`&#*V&]+W&`&`&u&$&H#=&<.H#<.<.<.<.<.<.<.i#I i#I 0& ",
" ] ^ { / 2%L%z&z&z&z&z&z&z&z&z&G&R%z%y%f.f.f.w$f.w$c#w$c#U$u%N&a$a$)*z%a$a$a$&&R%=*T&.*T&Z&T&Z&>*T&;*P&;*!*y%Y&P& ] ^ { P.N S%H&L&z&z&z&z&z&M&I&J&5&N V%_&_&_&_&_&_&4+_&4+k&F%O&#*`&$*]+,*`&#*O&9&=&<.H#<.<.<.<.<.<.<.i#<.i#I 0&i# ",
" ^ ] / ] R%*&z&z&z&z&z&z&z&z&s%R%z%P&f.f.f.w$f.t$w$#+c#U$c#R%N&a$a$S&N a$a$a$)*N Z&.*Z&Z&T&T&;*T&>*P&;*P&y%Y&P&Y& ^ ] P.] N F%H&I&L&z&z&L&I&I&r%S%N K%_&_&_&_&_&_&_&h&4+h&H#J%r&#*`&@*e&@*`&`&$*I%i#H#<.H#<.<.<.<.<.i#<.i#I 0&i#0& ",
" ] m%] m%2&N 5%z&z&z&z&z&s%*&N R%3&f.f.f.'*f.w$w$c#c#U$c#**R%N&a$a$Q&N S&a$a$Q&N t% *T&T&Z&>*Z&;*P&;*P&>*Y&!*Y&Y& ] P.] P.$&I%K%c%J&]&]&B&r%)&[&I%'&_&_&_&_&_&_&_&4+4+h&4+H#$&r&#*`&,*G%@*`&`&W&G%)&}$<.<.<.<.<.<.i#<.i#<.i#i#0&0& ",
" m%] m%/ / D%N z%O%O%O%1%N 1%4&x&f.f.f.w$f.#+#+c##+U$c#&*&*R%N&a$a$a$N S&a$a$a$z%}&T&T&Z&;*T&;*P&;*P&;*Y&P&Y&Y&Y& P.] P.P.4+K%I%F%$&S%S%$&[&I%5&I _&_&_&_&_&_&h&4+_&h&4+4+w&$&r&#*`&,*e&$*`&G#G#e&S%<.<.H#<.<.<.i#<.i#<.0&i#0&0&0& ",
" ^ / m%m%/ b 3&2&*&A%}&|%4%K f.f.f.f.#+f.#+#+c##+&*c#**&*&*u%N&a$a$a$z%)*a$a$a$O&%&T&T&;*T&y%!*y%!*y%Y&P&Y&Y&Y&Y& ^ P.P.P.P.t&w&'&S%$&$&5&E%I 4+_&_&_&_&_&h&_&4+h&4+4+=&4+H#J%r&G#`&X&u&V&G#`&#*r&F%<.<.<.<.I i#I i#I 0&i#0&0&0&0& ",
" ( / ( / b m%b b b K 4 f.b f.(&f.f.w$f.w$w$c##+&*#+**U$****D%R&a$a$a$R&N&a$a$a$N&1%Z&;*T&y%!*y%!*y%Y&!*Y&Y&Y&Y&Y& g%P.g%P.x%P.P.x%_&4+_&_&x%_&x%_&_&_&_&_&_&4+_&=&_&=&h&=&=&5&u&X&`&X&r&%*X&`&`&V&I%<.<.<.I i#I i#I 0&i#i#0&0&0&0& ",
" m%/ / b / b b 4 K 4 f.b f.f.f.f.'*f.#+'*c#w$**w$**&*&*&*&*D%R&a$a$a$O&&&a$a$a$S&N Y&Z&y%!*y%!*y%Y&P&Y&Y&Y&Y&Y&~* P.P.P.P.P.x%x%P.K P._&x%_&_&_&_&_&_&h&_&4+_&=&_&=&4+=&4+=&5&u&X&`&`&O&u&X&`&`&,*I%E%<.I i#I i#I i#i#0&0&0&0&0&0& ",
" ( m%b / b b K b K (&K x&f.f.f.w$f.w$c#w$c#U$c#&*****&*&*=*|%&&Q&Q&Q&N&R&Q&Q&Q&Q&z%t%P&>*P&;*P&Y&P&Y&Y&Y&Y&Y&~*Y& g%P.x%P.P.x%K x%K x%K _&_&_&_&_&_&_&4+_&4+h&4+4+=&4+=&4+k&V%J%W&X&X&%*u&W&X&X&W&9&K%i#<.i#<.i#0&i#0&0&0&0&0&0&0& ",
" ",
" "};

View file

@ -1,15 +0,0 @@
# This file is processed by GNU automake to generate Makefile.in
INCLUDES = -I$(top_srcdir)/pixmaps
bin_PROGRAMS = wmnotify
wmnotify_SOURCES = wmnotify.c wmnotify.h options.c options.h configfile.c configfile.h \
xevents.c xevents.h dockapp.c dockapp.h sound.c sound.h \
network.c network.h pop3.c pop3.h imap.c imap.h ssl.c ssl.h common.h
CLEANFILES = *~
DISTCLEANFILES = .deps/*.P
MAINTAINERCLEANFILES = Makefile.in
# we want these in the dist tarball
EXTRA_DIST =

View file

@ -1,58 +0,0 @@
/*
* common.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef COMMON_H
#define COMMON_H 1
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#if STDC_HEADERS
# include <string.h>
#elif HAVE_STRINGS_H
# include <strings.h>
#endif
/* Common constants. */
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# define EXIT_FAILURE 1
#endif
/* Returns TRUE if the strings 'a' and 'b' are equal. */
#define STREQ(a, b) (strcmp((a), (b)) == 0)
/* Returns TRUE if the first 'c' characters of strings 'a' and 'b' are equal. */
#define STREQ_LEN(a, b, c) (strncmp((a), (b), (c)) == 0)
inline void
ErrorLocation( const char *file, int line );
/*@out@*/ /*@only@*/
void *
xmalloc( size_t size, const char *filename, int line_number );
#endif /* COMMON_H */

View file

@ -1,427 +0,0 @@
/*
* configfile.c -- Parsing the configuration file
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdbool.h>
#if STDC_HEADERS
# include <string.h>
#elif HAVE_STRINGS_H
# include <strings.h>
#endif
#include <pwd.h>
#include "common.h"
#include "wmnotify.h"
#include "configfile.h"
#define LINE_BUFFER_LEN 256
/* Name of configuration file in user's home directory. */
const static char default_config_filename[] = ".wmnotifyrc";
const static char delimiter_single_arg[] = " \n";
const static char delimiter_multiple_arg[] = "#\n";
static void
CreateDefaultConfigurationFile( char *file )
{
int status;
FILE *fp;
fp = fopen( file, "w" );
if( fp == NULL ) {
fprintf( stderr, "%s: Can't create file \"%s\"\n", PACKAGE, file );
exit( EXIT_FAILURE );
}
/* Changing permissions so that only the user can read/modify the file. */
status = chmod( file, S_IRUSR | S_IWUSR );
if( status < 0 ) {
fprintf( stderr, "%s: Can't set permission bits on file \"%s\"\n", PACKAGE, file );
exit( EXIT_FAILURE );
}
fprintf( fp, "# ~/.wmnotifyrc -- Default configuration file for wmnotify\n\n" );
fprintf( fp, "# Replace all 'xxxxxxxx' fields with your own settings.\n\n" );
fprintf( fp, "# Parameters preceded by a '#' character are optional.\n" );
fprintf( fp, "# You can set their values by removing the leading '#'.\n\n" );
fprintf( fp, "# Mail Protocol: POP3 or IMAP4.\n" );
fprintf( fp, "protocol POP3\n\n" );
fprintf( fp, "# Use SSL encrytion: 0=disable, 1=enable (optional, default is "
"disabled).\n" );
fprintf( fp, "use_ssl 0\n\n" );
fprintf( fp, "# Mail Server Name.\n" );
fprintf( fp, "server xxxxxxxx\n\n" );
fprintf( fp, "# Mail Server Port Number (optional, default is 110).\n" );
fprintf( fp, "port 110\n\n" );
fprintf( fp, "# Username.\n" );
fprintf( fp, "username xxxxxxxx\n\n" );
fprintf( fp, "# Password.\n" );
fprintf( fp, "password xxxxxxxx\n\n" );
fprintf( fp, "# IMAP folder name (optional, default is INBOX).\n" );
fprintf( fp, "# folder INBOX.some_folder\n\n" );
fprintf( fp, "# Mail Check Interval (in minutes, default is 5 minutes).\n" );
fprintf( fp, "#mailcheckdelay 5\n\n" );
fprintf( fp, "# Default mail client (optional).\n" );
fprintf( fp, "#mailclient sylpheed\n\n" );
fprintf( fp, "# Audio notification, 0=disable, 1=enable (optional, default is "
"disabled).\n" );
fprintf( fp, "enablebeep 0\n\n" );
fprintf( fp, "# Location of sound file for audio notification. If no sound file is\n" );
fprintf( fp, "# specified, the console beep will be used instead.\n" );
fprintf( fp, "audiofile /usr/local/share/sounds/halmsgs.wav\n\n" );
fprintf( fp, "# Volume (0 to 100%%).\n" );
fprintf( fp, "volume 100\n" );
fprintf( stderr, "%s: A default configuration file has been created in your "
"home directory: \"%s\"\n", PACKAGE, file );
fprintf( stderr, "You must edit it before running %s.\n", PACKAGE );
status = fclose( fp );
if( status != EXIT_SUCCESS ) {
fprintf( stderr, "%s: Error closing file \"%s\"\n", PACKAGE, file );
}
}
static void
ParseCommand( char *line, /*@out@*/ char *argv[] )
{
int argc = 0;
while( *line != '\0' ) { /* if not the end of line ....... */
while( *line == ' ' || *line == '\t' || *line == '\n' ) {
*line++ = '\0'; /* replace white spaces with 0 */
}
*argv++ = line; /* save the argument position */
while( *line != '\0' && *line != ' ' && *line != '\t' && *line != '\n' ) {
line++; /* skip the argument until ... */
}
argc++;
if( argc == ARGV_LIMIT ) {
fprintf( stderr, "%s: Too much arguments for external command\n",
PACKAGE );
exit( EXIT_FAILURE );
}
}
*argv = NULL; /* mark the end of argument list */
}
static char *
GetArguments( char *parameter, bool single_argument )
{
char *token;
if( single_argument ) {
token = strtok( NULL, delimiter_single_arg );
}
else {
/* We search for a string terminated by either a '#' character (the rest of
the line is then a comment, which is simply ignored ), or the end of line
character '\n'. */
token = strtok( NULL, delimiter_multiple_arg );
}
if( token == NULL ) {
fprintf( stderr, "%s: Missing argument for \"%s\" parameter in "
"configuration file.\n", PACKAGE, parameter );
exit( EXIT_FAILURE );
}
return token;
}
static int
GetNumber( char *token, char *parameter )
{
char temp[32]; /* Check size ??? */
if( sscanf( token, "%[0123456789]", temp ) == 0 ) {
fprintf( stderr, "%s: Invalid argument for \"%s\" parameter in "
"configuration file.\n", PACKAGE, parameter );
exit( EXIT_FAILURE );
}
return atoi( temp );
}
static void
ParseConfigurationFile( FILE *file )
{
char line[LINE_BUFFER_LEN];
char *token;
bool protocol_found = false;
bool server_found = false;
bool username_found = false;
bool password_found = false;
const char *err_string = NULL;
/* Default values for optional parameters. */
strcpy( wmnotify_infos.imap_folder, "INBOX"); /* Default IMAP folder. */
wmnotify_infos.port = 110;
wmnotify_infos.mail_check_interval = 60; /* 1 minute interval. */
wmnotify_infos.audible_notification = false; /* Disabled. */
wmnotify_infos.use_ssl = false; /* Disabled. */
wmnotify_infos.mail_client_argv[0] = NULL; /* No default command. */
wmnotify_infos.audiofile[0] = '\0'; /* No default audio file. */
wmnotify_infos.volume = 100; /* 100% volume. */
/* Reading one line of data from the configuration file. */
/* char *fgets(char *s, int size, FILE *stream);
Reading stops after an EOF or a newline. If a newline is read, it is
stored into the buffer. A '\0' is stored after the last character in
the buffer. */
while( fgets( line, LINE_BUFFER_LEN, file ) != NULL ) {
token = strtok( line, delimiter_single_arg );
if( ( token == NULL ) || ( token[0] == '#' ) ) {
continue; /* Next iteration of the while() loop (next line). */
}
if( STREQ( token, "protocol" ) ) {
token = GetArguments( "protocol", true );
if( STREQ( token, "POP3" ) == true ) {
wmnotify_infos.protocol = POP3_PROTOCOL;
}
else if( STREQ( token, "IMAP4" ) == true ) {
wmnotify_infos.protocol = IMAP4_PROTOCOL;
}
else {
fprintf( stderr, "%s: protocol must be POP3 or IMAP4.\n", PACKAGE );
exit( EXIT_FAILURE );
}
protocol_found = true;
}
else if( STREQ( token, "imap_folder" ) ) {
token = GetArguments( "imap_folder", true );
/* Should check size before using strcpy(), or use strncopy() instead. */
strcpy( wmnotify_infos.imap_folder, token );
}
else if( STREQ( token, "use_ssl" ) ){
int number;
token = GetArguments( "use_ssl", true );
number = GetNumber( token, "use_ssl" );
if( number == 0 ) {
wmnotify_infos.use_ssl = false;
}
else if( number == 1 ) {
#if HAVE_SSL
wmnotify_infos.use_ssl = true;
#else
fprintf( stderr, "%s error: You must compile %s with SSL support to\n" \
"set parameter 'use_ssl' to true in configuration file\n", PACKAGE, PACKAGE );
exit( EXIT_FAILURE );
#endif
}
else {
fprintf( stderr, "%s: Invalid value for parameter 'use_ssl' in\n" \
"configuration file (must be 0 or 1): %d\n", PACKAGE, number );
exit( EXIT_FAILURE );
}
}
else if( STREQ( token, "server" ) ) {
token = GetArguments( "server", true );
strncpy( wmnotify_infos.server_name, token, MAX_STR_LEN );
server_found = true;
}
else if( STREQ( token, "port" ) ) {
token = GetArguments( "port", true );
wmnotify_infos.port = (u_int16_t) GetNumber( token, "port" );
}
else if( STREQ( token, "username" ) ) {
token = GetArguments( "username", true );
strncpy( wmnotify_infos.username, token, MAX_STR_LEN );
username_found = true;
}
else if( STREQ( token, "password" ) ) {
token = GetArguments( "password", true );
strncpy( wmnotify_infos.password, token, MAX_STR_LEN );
password_found = true;
}
else if( STREQ( token, "mailcheckdelay" ) ) {
int delay; /* delay in minutes. */
token = GetArguments( "mailcheckdelay", true );
/* GetNumber() will exit if a negative number is entered. */
delay = GetNumber( token, "mailcheckdelay" );
if( delay == 0 ) {
fprintf( stderr, "%s: Mail check interval must be greater than '0'\n",
PACKAGE );
exit( EXIT_FAILURE );
}
wmnotify_infos.mail_check_interval = (unsigned int) delay * 60;
}
else if( STREQ( token, "mailclient" ) ) {
token = GetArguments( "mailclient", false ); /* Multiple arguments */
strcpy( wmnotify_infos.mail_client_command, token );
ParseCommand( wmnotify_infos.mail_client_command,
wmnotify_infos.mail_client_argv );
}
else if( STREQ( token, "enablebeep" ) ){
int number;
token = GetArguments( "enablebeep", true );
number = GetNumber( token, "enablebeep" );
if( number == 0 ) {
wmnotify_infos.audible_notification = false;
}
else if( number == 1 ) {
wmnotify_infos.audible_notification = true;
}
else {
fprintf( stderr, "%s: Invalid value for for parameter 'enablebeep' in\n" \
"configuration file (must be 0 or 1): %d\n", PACKAGE, number );
exit( EXIT_FAILURE );
}
}
else if( STREQ( token, "audiofile" ) ) {
token = GetArguments( "audiofile", true );
/* Should check size before using strcpy(), or use strncopy() instead. */
strcpy( wmnotify_infos.audiofile, token );
}
else if( STREQ( token, "volume" ) ) {
token = GetArguments( "volume", true );
wmnotify_infos.volume = GetNumber( token, "volume" );
}
else {
fprintf( stderr, "%s: invalid parameter in configuration file: %s\n", PACKAGE,
token );
exit( EXIT_FAILURE );
}
token = strtok( NULL, delimiter_single_arg );
if( ( token != NULL ) && ( token[0] != '#' ) ) {
fprintf( stderr, "%s: Garbage at end of line in configuration file: %s\n", PACKAGE,
token );
exit( EXIT_FAILURE );
}
}
if( protocol_found == false ) {
err_string = "protocol";
}
else if( server_found == false ) {
err_string = "server";
}
else if( username_found == false ) {
err_string = "username";
}
else if( password_found == false ) {
err_string = "password";
}
else {
return; /* success */
}
/* Failure. */
fprintf( stderr, "%s: Mandatory parameter \"%s\" missing from configuration "
"file.\n", PACKAGE, err_string );
exit( EXIT_FAILURE );
}
/*******************************************************************************
* Read and parse the configuration file in the user's home directory
******************************************************************************/
void
ConfigurationFileInit( void )
{
FILE *fp;
int status;
size_t len;
/* Check if an optional configuration file was specified on the command
line. */
if( wmnotify_infos.optional_config_file != NULL ) {
/* Trying to open the file. */
fp = fopen( wmnotify_infos.optional_config_file, "r" );
if( fp == NULL ) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
}
else {
/* Using the default configuration file. */
char *home_dir;
char *default_config_file;
home_dir = getenv("HOME");
if( home_dir == NULL ) {
/* We're trying to expand ~/, but HOME isn't set. */
struct passwd *pw = getpwuid( getuid() );
if( pw != NULL ) {
home_dir = pw->pw_dir;
}
else {
fprintf( stderr, "%s: Couldn't determine user's home directory path\n",
PACKAGE );
exit( EXIT_FAILURE );
}
}
/* We add 1 to the length for the terminating character '\0'. */
len = strlen( home_dir ) + strlen( "/" ) + strlen( default_config_filename )
+ 1;
default_config_file = xmalloc( len, __FILE__, __LINE__ );
sprintf( default_config_file, "%s/%s", home_dir, default_config_filename );
fp = fopen( default_config_file, "r" );
if( fp == NULL ) {
/* If we cannot open the default configuration file, it probably means
it is missing, so we create it. */
CreateDefaultConfigurationFile( default_config_file );
free( default_config_file );
exit( EXIT_FAILURE );
}
free( default_config_file );
}
ParseConfigurationFile( fp );
status = fclose( fp );
if( status != EXIT_SUCCESS ) {
fprintf( stderr, "%s: Error closing configuration file.\n", PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
}

View file

@ -1,27 +0,0 @@
/*
* configfile.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef CONFIGFILE_H
#define CONFIGFILE_H 1
void
ConfigurationFileInit( void );
#endif /* CONFIGFILE_H */

View file

@ -1,300 +0,0 @@
/*
* dockapp.c -- routines for managing dockapp windows and icons.
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Define filename_M */
#define DOCKAPP_M 1
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
#include "common.h"
#include "dockapp.h"
#define XLIB_FAILURE 0
#define XLIB_SUCCESS 1
/* Specifies the border width */
#define BWIDTH 1
/* Width and height in pixels of Window Maker icons. */
#define ICON_SIZE 64
static void
CreateIconFromXpmData( char *pixmap_data[] )
{
int status;
dockapp.xpm_icon.attributes.valuemask |=
( XpmReturnPixels | XpmReturnExtensions );
/* Using the XPM library to read XPM data from the array in the included XPM
file. The 'shapemask' Pixmap variable is set to an additional 1-bit deep
pixmap that can then be used as a shape mask for the XShapeCombineMask()
function. */
status = XpmCreatePixmapFromData( dockapp.display, dockapp.root_win,
pixmap_data, &dockapp.xpm_icon.image,
&dockapp.xpm_icon.shapemask,
&dockapp.xpm_icon.attributes );
if( status != XpmSuccess ) {
fprintf( stderr, "%s: XpmCreatePixmapFromData() failed\n", PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
}
static Pixel
GetColor( char *name )
{
int status;
bool res;
XColor color;
XWindowAttributes attributes;
status = XGetWindowAttributes( dockapp.display, dockapp.root_win,
&attributes );
if( status == XLIB_FAILURE ) {
fprintf( stderr, "%s: XGetWindowAttributes() failed\n", PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
color.pixel = 0;
res = (bool) XParseColor( dockapp.display, attributes.colormap, name,
&color );
if( res == false ) {
fprintf( stderr, "%s: Can't parse %s.\n", PACKAGE, name );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
res = (bool) XAllocColor( dockapp.display, attributes.colormap, &color );
if( res == false ) {
fprintf( stderr, "%s: Can't allocate %s.\n", PACKAGE, name );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
return color.pixel;
}
static void
flush_expose( Window win )
{
XEvent dummy;
bool res = true;
while( res != false ) {
res = (bool) XCheckTypedWindowEvent( dockapp.display, win, Expose, &dummy );
}
}
void
RedrawWindow( void )
{
flush_expose( dockapp.iconwin );
(void) XCopyArea( dockapp.display, dockapp.xpm_icon.image, dockapp.iconwin,
dockapp.NormalGC, 0, 0, dockapp.xpm_icon.attributes.width,
dockapp.xpm_icon.attributes.height, 0, 0 );
flush_expose( dockapp.win );
(void) XCopyArea( dockapp.display, dockapp.xpm_icon.image, dockapp.win,
dockapp.NormalGC, 0, 0, dockapp.xpm_icon.attributes.width,
dockapp.xpm_icon.attributes.height, 0, 0 );
}
void
copyXPMArea( int x, int y, unsigned int sx, unsigned int sy, int dx, int dy )
{
(void) XCopyArea( dockapp.display, dockapp.xpm_icon.image,
dockapp.xpm_icon.image, dockapp.NormalGC, x, y, sx, sy,
dx, dy );
}
/*******************************************************************************
* New window creation and initialization for a Dockable Application
******************************************************************************/
void
InitDockAppWindow( int argc, char *argv[], char *pixmap_data[],
char *display_arg, char *geometry_arg )
{
XGCValues gcv;
XSizeHints size_hints;
XWMHints wm_hints;
int status;
int gravity = 0; /* Used to store the gravity value returned by XWMGeometry,
but not used. */
/* Opening a connection to the X server. */
dockapp.display = XOpenDisplay( display_arg );
if( dockapp.display == NULL ) {
fprintf( stderr, "%s: Can't open display: %s\n", PACKAGE,
XDisplayName( display_arg ) );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
dockapp.screen = DefaultScreen( dockapp.display );
dockapp.root_win = RootWindow( dockapp.display, dockapp.screen );
dockapp.d_depth = DefaultDepth( dockapp.display, dockapp.screen );
/* Create a window to hold the stuff */
size_hints.flags = USSize | USPosition;
size_hints.x = 0;
size_hints.y = 0;
/* Constructing window's geometry information. */
/* XWMGeometry() returns an 'int', but Xlib documentation doesn't explain
it's meaning. */
XWMGeometry( dockapp.display, dockapp.screen, geometry_arg, NULL, BWIDTH,
&size_hints, &size_hints.x, &size_hints.y, &size_hints.width,
&size_hints.height, &gravity );
size_hints.width = ICON_SIZE;
size_hints.height = ICON_SIZE;
dockapp.back_pix = GetColor("white");
dockapp.fore_pix = GetColor("black");
dockapp.win = XCreateSimpleWindow( dockapp.display, dockapp.root_win,
size_hints.x, size_hints.y,
(unsigned int) size_hints.width,
(unsigned int) size_hints.height,
BWIDTH, dockapp.fore_pix,
dockapp.back_pix );
dockapp.iconwin = XCreateSimpleWindow( dockapp.display, dockapp.win,
size_hints.x, size_hints.y,
(unsigned int) size_hints.width,
(unsigned int) size_hints.height,
BWIDTH, dockapp.fore_pix,
dockapp.back_pix );
/* Configuring Client to Window Manager Communications. */
/* WM_NORMAL_HINTS property: size hints for a window in it's normal state. */
/* Replaces the size hints for the WM_NORMAL_HINTS property on the specified
window. */
XSetWMNormalHints( dockapp.display, dockapp.win, &size_hints );
/* Setting the WM_CLASS property. */
{
char *app_name = argv[0];
XClassHint wm_class;
/* The res_name member contains the application name.
The res_class member contains the application class. */
/* The name set in this property may differ from the name set as WM_NAME.
That is, WM_NAME specifies what should be displayed in the title bar and,
therefore, can contain temporal information (for example, the name of a
file currently in an editor's buffer). On the other hand, the name
specified as part of WM_CLASS is the formal name of the application that
should be used when retrieving the application's resources from the
resource database. */
wm_class.res_name = app_name;
wm_class.res_class = app_name;
(void) XSetClassHint( dockapp.display, dockapp.win, &wm_class );
}
/* Setting the WM_NAME property.
This specifies what should be displayed in the title bar (usually the
application name). */
{
XTextProperty text_prop;
char *app_name = argv[0];
const int string_count = 1;
status = XStringListToTextProperty( &app_name, string_count, &text_prop );
if( status == 0 ) {
fprintf( stderr, "%s: XStringListToTextProperty() failed\n", PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
XSetWMName( dockapp.display, dockapp.win, &text_prop );
/* Freing the storage for the value field. */
(void) XFree( text_prop.value );
}
/* WM_HINTS --> Additional hints set by the client for use by the Window
Manager. */
/* XWMHints wm_hints; */
/* WithdrawnState, NormalState or IconicState. Must be set to WithdrawnState
for DockApp. */
wm_hints.flags = StateHint | IconWindowHint | IconPositionHint |
WindowGroupHint;
wm_hints.initial_state = WithdrawnState; /* Withdrawn, Normal */
wm_hints.icon_window = dockapp.iconwin;
wm_hints.icon_x = size_hints.x;
wm_hints.icon_y = size_hints.y;
wm_hints.window_group = dockapp.win;
(void) XSetWMHints( dockapp.display, dockapp.win, &wm_hints );
/* Sets the WM_COMMAND property. This sets the command and arguments used to
invoke the application. */
(void) XSetCommand( dockapp.display, dockapp.win, argv, argc );
/* ... */
(void) XSelectInput( dockapp.display, dockapp.win,
ButtonPressMask | ExposureMask | ButtonReleaseMask |
PointerMotionMask | StructureNotifyMask );
(void) XSelectInput( dockapp.display, dockapp.iconwin,
ButtonPressMask | ExposureMask | ButtonReleaseMask |
PointerMotionMask | StructureNotifyMask );
/* Create GC for drawing */
gcv.foreground = dockapp.fore_pix;
gcv.background = dockapp.back_pix;
gcv.graphics_exposures = 0;
dockapp.NormalGC = XCreateGC( dockapp.display, dockapp.root_win,
GCForeground | GCBackground |
GCGraphicsExposures, &gcv );
/* Convert XPM data to XImage */
CreateIconFromXpmData( pixmap_data );
XShapeCombineMask( dockapp.display, dockapp.win, ShapeBounding, 0, 0,
dockapp.xpm_icon.shapemask, ShapeSet );
XShapeCombineMask( dockapp.display, dockapp.iconwin, ShapeBounding, 0, 0,
dockapp.xpm_icon.shapemask, ShapeSet );
/* Making the new window visible. */
(void) XMapWindow( dockapp.display, dockapp.win );
}

View file

@ -1,67 +0,0 @@
/*
* dockapp.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef DOCKAPP_H
#define DOCKAPP_H 1
#include <X11/xpm.h>
typedef struct XpmIcon
{
XpmAttributes attributes;
Pixmap shapemask;
Pixmap image;
} XpmIcon;
typedef struct dockapp_t
{
Display *display;
Window root_win;
int screen;
int d_depth;
Pixel back_pix;
Pixel fore_pix;
Window iconwin;
Window win;
GC NormalGC;
XpmIcon xpm_icon;
} dockapp_t;
void
InitDockAppWindow( int argc, char *argv[], char *pixmap_data[],
char *display_arg, char *geometry_arg );
void
RedrawWindow( void );
void
copyXPMArea( int x, int y, unsigned int sx, unsigned int sy, int dx, int dy );
/* Exported variables */
#undef _SCOPE_
#ifdef DOCKAPP_M
#define _SCOPE_ /**/
#else
#define _SCOPE_ extern
#endif
_SCOPE_ dockapp_t dockapp;
#endif /* DOCKAPP_H */

View file

@ -1,309 +0,0 @@
/*
* imap.c -- Routines for communication with an IMAP server
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Define filename_M */
#define IMAP_M 1
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ctype.h> /* for isdigit() */
#include "common.h"
#include "wmnotify.h"
#include "network.h"
#include "imap.h"
#define IMAP4_ENDL "\r\n" /* CRLF */
#define IMAP4_CMD_CAPABILITY "CAPABILITY"
#define IMAP4_CMD_LOGIN "LOGIN"
#define IMAP4_CMD_SELECT "SELECT"
#define IMAP4_CMD_EXAMINE "EXAMINE"
#define IMAP4_CMD_LOGOUT "LOGOUT"
#define IMAP4_CMD_SEARCH_UNSEEN "SEARCH UNSEEN"
/* Responses from IMAP4 server. */
#define IMAP4_RSP_SUCCESS "OK"
#define IMAP4_RSP_FAILURE "NO"
#define IMAP4_RSP_PROTOCOL_ERR "BAD"
#define IMAP4_RSP_SEARCH_UNSEEN "* SEARCH " /* This is the line that will be returned by
* the IMAP4 server after receiving the
* "SEARCH UNSEEN" command, followed by the
* messages ID of the unseen messages. */
static int tlabel = 0;
static int tlabel_len;
static int unseen_string_found;
/* Defined in network.c */
extern char tx_buffer[WMNOTIFY_BUFSIZE + 1];
extern char rx_buffer[WMNOTIFY_BUFSIZE + 1];
static int
IMAP4_ReceiveResponse( void )
{
int len;
char *token;
char *stringp;
/* All interactions transmitted by client and server are in the form of
lines, that is, strings that end with a CRLF. The protocol receiver
of an IMAP4rev1 client or server is either reading a line, or is
reading a sequence of octets with a known count followed by a line. */
get_packet:
len = WmnotifyGetResponse( rx_buffer, WMNOTIFY_BUFSIZE );
if( len < 0 ) {
/* An error occured. WmnotifyGetResponse() should have printed an error message. */
goto error;
}
else if( len == 0 ) {
/* The return value will be 0 when the peer has performed an orderly shutdown. */
if( wmnotify_infos.debug ) {
fprintf( stderr, "IMAP server has closed connection.\n" );
}
goto error;
}
else if( len == WMNOTIFY_BUFSIZE ) {
if( wmnotify_infos.debug ) {
ErrorLocation( __FILE__, __LINE__ );
fprintf( stderr, "Response too big (%d bytes) to fit in receive buffer.\n", len );
}
goto error;
}
/* We suppose that, if a partial response packet was sent, it is not broken in the middle
of a line (to confirm). Normally, each string is terminated by CRLF. */
if( STREQ_LEN( &rx_buffer[ len - 2 ], IMAP4_ENDL, 2 ) == false ) {
/* No CRLF found at the end of the buffer --> not handled by wmnotify. */
ErrorLocation( __FILE__, __LINE__ );
fprintf( stderr, "Response buffer doesn't contain CRLF at the end.\n" );
goto error;
}
if( wmnotify_infos.debug ) {
printf( "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n" );
printf( "IMAP4 Server Response (size %d bytes):\n", len );
printf( "%s", rx_buffer );
printf( "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n" );
}
/* Converting the last CRLF into a LF followed by a NULL termination character. */
rx_buffer[ len - 2 ] = '\n';
rx_buffer[ len - 1 ] = '\0';
/* Check the Server Completion Response returned by the IMAP4 server. There are currently
* three Server Completion Responses codes: success ("OK"), failure ("NO") and protocol error
* ("BAD"). */
stringp = rx_buffer;
while( ( token = strsep( &stringp, "\n" ) ) != NULL ) {
/* In case no delimiter was found, the token is taken to
be the entire string *stringp, and *stringp is made NULL. */
if( stringp == NULL ) {
if( token[0] == '\0' ) {
/* This means we finished parsing the last line of the buffer, but we need to
get more data to continue process the next part of the IMAP4 response. */
goto get_packet;
}
else {
/* This should never happen. */
ErrorLocation( __FILE__, __LINE__ );
fprintf( stderr, " Delimiter not found in strsep() call.\n" );
goto error;
}
}
if( token == NULL ) {
/* This should never happen. */
ErrorLocation( __FILE__, __LINE__ );
fprintf( stderr, " NULL token returned by strsep().\n" );
goto error;
}
if( token[0] == '*' ) {
/* Untagged response. If there is a space after the SEARCH response, it means
* at least 1 message is unseen. */
if( STREQ_LEN( token, IMAP4_RSP_SEARCH_UNSEEN, strlen(IMAP4_RSP_SEARCH_UNSEEN) ) == true ) {
unseen_string_found = true;
}
}
else {
/* Must be the status... */
/* We check for the correct transaction label plus a space. */
if( STREQ_LEN( token, tx_buffer, tlabel_len + 1 ) == true ) {
token += tlabel_len + 1;
if( STREQ_LEN( token, IMAP4_RSP_SUCCESS, strlen(IMAP4_RSP_SUCCESS) ) == true ) {
goto end; /* OK, no errors. */
}
else if( STREQ_LEN( token, IMAP4_RSP_PROTOCOL_ERR, strlen(IMAP4_RSP_PROTOCOL_ERR) ) == true ) {
fprintf( stderr, "%s: Protocol error (%s).\n", PACKAGE, token );
goto error;
}
else if( STREQ_LEN( token, IMAP4_RSP_FAILURE, strlen(IMAP4_RSP_FAILURE) ) == true ) {
fprintf( stderr, "%s: Failure (%s).\n", PACKAGE, token );
goto error;
}
else {
fprintf( stderr, "%s: Unknown error code (%s).\n", PACKAGE, token );
goto error;
}
}
else {
fprintf( stderr, "%s: Error, transaction label mismatch.\n", PACKAGE );
goto error;
}
}
} /* while( token ) */
/* Get next part of IMAP4 response. */
goto get_packet;
end:
/* No error. */
return len;
error:
return -1;
}
static int
IMAP4_SendCommand( int argc, char *argv[] )
{
int len;
int i;
/* Adding Transaction Label. */
tlabel++;
tx_buffer[0] = 'A';
len = 1;
len += sprintf( tx_buffer + len, "%d", tlabel );
tlabel_len = len;
/* Adding command and it's arguments. */
for( i = 0; i < argc; i++ ) {
len += sprintf( tx_buffer + len, " %s", argv[i] );
}
if( wmnotify_infos.debug ) {
tx_buffer[len] = '\0';
printf( ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" );
printf( "IMAP4 Client Command (size %d bytes):\n%s\n", len, tx_buffer );
printf( ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" );
}
/* Adding termination characters. */
len += sprintf( tx_buffer + len, IMAP4_ENDL );
len = WmnotifySendData( tx_buffer, len );
if( len < 0 ) {
return EXIT_FAILURE;
}
len = IMAP4_ReceiveResponse();
if( len < 0 ) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int
IMAP4_CheckForNewMail( void )
{
char *argv[10];
int new_messages = 0;
int status;
status = ConnectionEstablish( wmnotify_infos.server_name, wmnotify_infos.port );
if( status != EXIT_SUCCESS ) {
new_messages = -1;
goto end;
}
argv[0] = IMAP4_CMD_LOGIN;
argv[1] = wmnotify_infos.username;
argv[2] = wmnotify_infos.password;
status = IMAP4_SendCommand( 3, argv );
if( status != EXIT_SUCCESS ) {
new_messages = -1;
goto imap4_logout;
}
/* Selecting the mailbox first. */
argv[0] = IMAP4_CMD_EXAMINE;
argv[1] = wmnotify_infos.imap_folder;
status = IMAP4_SendCommand( 2, argv );
if( status != EXIT_SUCCESS ) {
new_messages = -1;
goto imap4_logout;
}
/* Searching in selected mailbox for new messages. We must use the UNSEEN search criteria
* instead of NEW (combination of RECENT and UNSEEN). If there is a new message, RECENT
* and UNSEEN will have entries. But if we recheck again later, RECENT will report zero.
* RECENT, when set, simply means that there are new messages since our last visit.
But, on the other hand, when using EXAMINE, no messages should lose their RECENT flag. */
unseen_string_found = false;
argv[0] = IMAP4_CMD_SEARCH_UNSEEN;
argv[1] = "";
status = IMAP4_SendCommand( 1, argv );
if( status != EXIT_SUCCESS ) {
new_messages = -1;
goto imap4_logout;
}
if( unseen_string_found == true ) {
new_messages = 1;
}
imap4_logout:
argv[0] = IMAP4_CMD_LOGOUT;
status = IMAP4_SendCommand( 1, argv );
if( status != EXIT_SUCCESS ) {
new_messages = -1;
}
status = ConnectionTerminate();
if( status != EXIT_SUCCESS ) {
new_messages = -1;
}
end:
return new_messages;
}

View file

@ -1,35 +0,0 @@
/*
* imap.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef IMAP_H
#define IMAP_H 1
/* Exported variables */
#undef _SCOPE_
#ifdef IMAP_M
# define _SCOPE_ /**/
#else
# define _SCOPE_ extern
#endif
int
IMAP4_CheckForNewMail( void );
#endif /* IMAP_H */

View file

@ -1,253 +0,0 @@
/*
* network.c -- common routines for POP3 and IMAP protocols
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Define filename_M */
#define NETWORK_M 1
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "common.h"
#include "wmnotify.h"
#if HAVE_SSL
# include "ssl.h"
#endif
#include "network.h"
#define SEND_FLAGS 0
#define RECV_FLAGS 0
/* Common buffers for IMAP4 and POP3. */
char tx_buffer[WMNOTIFY_BUFSIZE + 1];
char rx_buffer[WMNOTIFY_BUFSIZE + 1];
int
SocketOpen( char *server_name, int port )
{
int status;
int sock_fd = -1;
struct hostent *hostinfo;
struct sockaddr_in serv_addr;
hostinfo = gethostbyname(server_name);
if( hostinfo == NULL ) {
herror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
goto error;
}
/* Open socket for Stream (TCP) */
sock_fd = socket( PF_INET, SOCK_STREAM, 0 );
if( sock_fd < 0 ) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
goto error;
}
/*---Initialize server address/port struct---*/
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
serv_addr.sin_addr = *((struct in_addr *) hostinfo->h_addr );
memset( &( serv_addr.sin_zero ), '\0', 8 ); /* Clear the rest of the structure. */
if( wmnotify_infos.debug ) {
printf( " Server IP = %s\n", inet_ntoa( serv_addr.sin_addr ) );
printf( " Server port = %d\n", ntohs(serv_addr.sin_port) );
}
/* Establishing connection. */
status = connect( sock_fd, (struct sockaddr *) &(serv_addr), sizeof(serv_addr) );
if( status < 0 ) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
goto error;
}
end:
return sock_fd;
error:
if( sock_fd >= 0 ) {
status = close( sock_fd );
if( status < 0 ) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
}
}
sock_fd = -1;
goto end;
}
int
ConnectionEstablish( char *server_name, int port )
{
int len;
char rx_buffer[1024]; /* Temporary... */
wmnotify_infos.sock_fd = SocketOpen( wmnotify_infos.server_name, wmnotify_infos.port );
if( wmnotify_infos.sock_fd < 0 ) {
goto error;
}
#if HAVE_SSL
if( wmnotify_infos.use_ssl == true ) {
int status;
status = InitSSL( wmnotify_infos.sock_fd );
if( status != EXIT_SUCCESS ) {
goto error;
}
}
#endif
/* Testing connection. */
len = WmnotifyGetResponse( rx_buffer, 1024 );
if( len < 0 ) {
goto error;
}
if( wmnotify_infos.debug ) {
rx_buffer[len] = 0;
printf(" Connect response:\n%s\n", rx_buffer );
}
return EXIT_SUCCESS;
error:
return EXIT_FAILURE;
}
int
ConnectionTerminate( void )
{
#if HAVE_SSL
if( wmnotify_infos.use_ssl == true ) {
SSL_free( ssl_infos.ssl ); /* release connection state */
}
#endif
close( wmnotify_infos.sock_fd ); /* close socket */
#if HAVE_SSL
if( wmnotify_infos.use_ssl == true ) {
SSL_CTX_free( ssl_infos.ctx ); /* release context */
}
#endif
return EXIT_SUCCESS;
}
int
WmnotifySendData( char *buffer, int size )
{
int len;
#if HAVE_SSL
if( wmnotify_infos.use_ssl == true ) {
len = SSL_write( ssl_infos.ssl, buffer, size ); /* Encrypt & send message */
if( len <= 0 ) {
SSL_get_error( ssl_infos.ssl, len );
len = -1;
}
return len;
}
#endif /* HAVE_SSL */
/* if errno = EINTR, it means the operation was interrupted by a signal before any data was
* sent. We must retry the operation in this case. */
do {
len = send( wmnotify_infos.sock_fd, buffer, size, SEND_FLAGS );
}
while( ( len < 0 ) && ( errno == EINTR ) );
if( len < 0 ) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
}
return len;
}
int
WmnotifyGetResponse( char *buffer, int max_size )
{
int len;
#if HAVE_SSL
if( wmnotify_infos.use_ssl == true ) {
len = SSL_read( ssl_infos.ssl, buffer, max_size ); /* Get reply & decrypt. */
switch( SSL_get_error( ssl_infos.ssl, len ) ) {
case SSL_ERROR_NONE:
/* Success. */
break;
case SSL_ERROR_ZERO_RETURN:
fprintf( stderr, "%s: SSL_read() connection closed.\n", PACKAGE );
break;
case SSL_ERROR_SYSCALL:
fprintf( stderr, "%s: SSL_read() I/O error.\n", PACKAGE );
goto ssl_error;
case SSL_ERROR_SSL:
fprintf( stderr, "%s: SSL_read() protocol error.\n", PACKAGE );
goto ssl_error;
default:
fprintf( stderr, "%s: SSL_read() error.\n", PACKAGE );
goto ssl_error;
}
return len;
ssl_error:
return -1;
}
#endif /* HAVE_SSL */
/* if errno = EINTR, it means the operation was interrupted by a signal before any data was
* read. We must retry the operation in this case. */
do {
len = recv( wmnotify_infos.sock_fd, buffer, max_size, RECV_FLAGS );
}
while( ( len < 0 ) && ( errno == EINTR ) );
if( len < 0 ) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
}
return len;
}

View file

@ -1,52 +0,0 @@
/*
* network.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef NETWORK_H
#define NETWORK_H 1
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* POP3 responses may be up to 512 characters long, including the terminating
CRLF. IMAP4 responses can be more than 1024 characters. */
#define WMNOTIFY_BUFSIZE 10240
int
SocketOpen( char *server_name, int port );
int
ConnectionEstablish( char *server_name, int port );
int
ConnectionTerminate( void );
int
WmnotifySendData( char *buffer, int size );
int
WmnotifyGetResponse( char *buffer, int max_size );
#endif /* NETWORK_H */

View file

@ -1,183 +0,0 @@
/*
* options.c -- functions for processing command-line options and arguments
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#if STDC_HEADERS
# include <string.h>
#elif HAVE_STRINGS_H
# include <strings.h>
#endif
#include "common.h"
#include "wmnotify.h"
#include "options.h"
/*******************************************************************************
* Display the help message and exit
******************************************************************************/
static void
DisplayUsage( void )
{
printf( "Usage: %s [OPTIONS]...\n", PACKAGE );
printf( "Email notification for single POP3 or IMAP4 account.\n\n" );
printf( " -c <config-file> use alternate configuration file\n" );
printf( " -d Display debugging messages.\n" );
printf( " -display <host:display> X display name\n" );
printf( " -geometry +XPOS+YPOS initial window position\n" );
printf( " -h display this help and exit\n" );
printf( " -version display version information and exit\n");
printf( "\n" );
}
/*******************************************************************************
* Display version information and exit
******************************************************************************/
static void
DisplayVersion( void )
{
printf( "\n" );
printf( " %s, version %s\n", PACKAGE, VERSION );
printf( " Written by Hugo Villeneuve\n\n" );
}
static void
InvalidOption( const char *message, /*@null@*/ const char *string )
{
if( string == NULL ) {
fprintf(stderr, "%s: %s\n", PACKAGE, message );
}
else {
fprintf(stderr, "%s: %s %s\n", PACKAGE, message, string );
}
fprintf(stderr, "Try `%s -h' for more information.\n", PACKAGE );
exit( EXIT_FAILURE );
}
/*******************************************************************************
* Initializes the different options passed as arguments on the command line.
******************************************************************************/
void
ParseCommandLineOptions( int argc, char *argv[] )
{
int i;
char *token;
bool config_file_on = false;
bool display_on = false;
bool geometry_on = false;
/* Default values. */
wmnotify_infos.debug = false;
for( i = 1; i < argc; i++ ) {
token = argv[i];
switch( token[0] ) {
case '-':
/* Processing options names */
switch( token[1] ) {
case 'c':
if( strlen( &token[1] ) == 1 ) {
config_file_on = true;
}
else {
InvalidOption( "invalid option", token );
}
break;
case 'd':
if( STREQ( "display", &token[1] ) ) {
display_on = true;
}
else if( strlen( &token[1] ) == 1 ) {
wmnotify_infos.debug = true;
}
break;
case 'g':
if( STREQ( "geometry", &token[1] ) ) {
geometry_on = true;
}
else {
InvalidOption( "invalid option", token );
}
break;
case 'h':
if( strlen( &token[1] ) == 1 ) {
DisplayUsage();
exit( EXIT_SUCCESS );
}
InvalidOption( "invalid option", token );
break;
case 'v' :
if( STREQ( "version", &token[1] ) ) {
DisplayVersion();
exit( EXIT_SUCCESS );
}
else {
InvalidOption( "invalid option", token );
}
break;
default:
InvalidOption( "invalid option", token );
break;
} /* end switch( token[1] ) */
break;
default:
/* Processing options arguments */
if( config_file_on != false ) {
wmnotify_infos.optional_config_file = token;
/*strcpy( config_file_name, token );*/
config_file_on = false;
}
else if( display_on != false ) {
display_on = false;
wmnotify_infos.display_arg = token;
}
else if( geometry_on != false ) {
geometry_on = false;
wmnotify_infos.geometry_arg = token;
}
else {
InvalidOption( "invalid option", token );
}
break;
} /* end switch( token[0] ) */
} /* end for */
if( config_file_on != false ) {
InvalidOption( "missing configuration file parameter", NULL );
}
else if( display_on != false ) {
InvalidOption( "missing display parameter", NULL );
}
else if( geometry_on != false ) {
InvalidOption( "missing geometry parameter", NULL );
}
}

View file

@ -1,27 +0,0 @@
/*
* options.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef OPTIONS_H
#define OPTIONS_H 1
void
ParseCommandLineOptions( int argc, char *argv[] );
#endif /* OPTIONS_H */

View file

@ -1,197 +0,0 @@
/*
* pop3.c -- Routines for communication with a pop3 server
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Define filename_M */
#define POP3_M 1
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include "common.h"
#include "wmnotify.h"
#include "network.h"
#include "pop3.h"
/* Defined in network.c */
extern char tx_buffer[WMNOTIFY_BUFSIZE + 1];
extern char rx_buffer[WMNOTIFY_BUFSIZE + 1];
static int
POP3_ReceiveResponse( void )
{
int len;
len = WmnotifyGetResponse( rx_buffer, WMNOTIFY_BUFSIZE );
if( len < 0 ) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
return len;
}
rx_buffer[ len - 2 ] = '\0';
if( wmnotify_infos.debug ) {
printf( "Response: \"%s\"\n", rx_buffer );
}
/* No error in recv at this point. Now we parse response from POP3 server. */
/* Check the status indicator returned by the POP3 server.
There are currently two status indicators: positive ("+OK") and negative
("-ERR"). Servers MUST send the status indicators in upper case. */
if( STREQ_LEN( rx_buffer, POP3_RSP_SUCCESS, strlen(POP3_RSP_SUCCESS) ) == false ) {
fprintf( stderr, "%s: Error, POP3 server responded:\n \"%s\"\n", PACKAGE, rx_buffer );
len = -1;
}
return len;
}
static int
POP3_SendCommand( int argc, char *argv[] )
{
int len;
int i;
/* Adding command and it's arguments. */
for( i = 0, len = 0; i < argc; i++ ) {
len += sprintf( tx_buffer + len, "%s", argv[i] );
if( i != ( argc - 1 ) ) {
len += sprintf( tx_buffer + len, " " );
}
}
if( wmnotify_infos.debug ) {
tx_buffer[len] = '\0';
printf( "Command: \"%s\"\n", tx_buffer );
}
/* Adding termination characters. */
len += sprintf( tx_buffer + len, POP3_ENDL );
len = WmnotifySendData( tx_buffer, len );
if( len < 0 ) {
return EXIT_FAILURE;
}
len = POP3_ReceiveResponse();
if( len < 0 ) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
/* Return the number of new messages on success, -1 on error. */
static int
POP3_ParseStatCommand( void )
{
int new_messages;
char *token;
/* STAT command:
* The positive response consists of "+OK" followed by a single space, the number of messages
* in the maildrop, a single space, and the size of the maildrop in octets. */
token = strtok( rx_buffer, " " );
token = strtok( NULL, " " );
if( token != NULL ) {
/* Do more checks for digits... */
new_messages = atoi( token );
}
else {
fprintf( stderr, "%s: Error parsing \"STAT\" response", PACKAGE );
new_messages = -1;
}
return new_messages;
}
int
POP3_CheckForNewMail( void )
{
int status;
int new_messages = -1;
char *argv[10];
status = ConnectionEstablish( wmnotify_infos.server_name, wmnotify_infos.port );
if( status != EXIT_SUCCESS ) {
return -1;
}
/* Sending username. */
argv[0] = POP3_CMD_USERNAME;
argv[1] = wmnotify_infos.username;
status = POP3_SendCommand( 2, argv );
if( status != EXIT_SUCCESS ) {
goto pop3_close_connection;
}
/* Sending password. */
argv[0] = POP3_CMD_PASSWORD;
argv[1] = wmnotify_infos.password;
status = POP3_SendCommand( 2, argv );
if( status != EXIT_SUCCESS ) {
goto pop3_close_connection;
}
/* Sending STAT command to inquiry about new messages. */
argv[0] = POP3_CMD_STAT;
status = POP3_SendCommand( 1, argv );
if( status != EXIT_SUCCESS ) {
goto pop3_close_connection;
}
/* Parsing STAT command. */
new_messages = POP3_ParseStatCommand();
if( new_messages < 0 ) {
goto pop3_close_connection;
}
/* Sending QUIT command. */
argv[0] = POP3_CMD_QUIT;
status = POP3_SendCommand( 1, argv );
if( status != EXIT_SUCCESS ) {
new_messages = -1;
goto pop3_close_connection;
}
pop3_close_connection:
status = ConnectionTerminate();
if( status != EXIT_SUCCESS ) {
new_messages = -1;
}
return new_messages;
}

View file

@ -1,54 +0,0 @@
/*
* pop3.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef POP3_H
#define POP3_H 1
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* Exported variables */
#undef _SCOPE_
#ifdef POP3_M
# define _SCOPE_ /**/
#else
# define _SCOPE_ extern
#endif
#define POP3_ENDL "\r\n" /* CRLF */
#define POP3_CMD_USERNAME "USER"
#define POP3_CMD_PASSWORD "PASS"
#define POP3_CMD_STAT "STAT"
#define POP3_CMD_QUIT "QUIT"
#define POP3_RSP_SUCCESS "+OK"
#define POP3_RSP_FAILURE "-ERR"
int
POP3_CheckForNewMail( void );
#endif /* POP3_H */

View file

@ -1,336 +0,0 @@
/*
* sound.c -- Plays sound from file.
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
* Based on the 'sndfile-play' demo program from 'libsndfile'
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#if defined(HAVE_SNDFILE)
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#if defined(__linux__)
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/soundcard.h>
#elif( defined(sun) && defined(unix) )
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/audioio.h>
#endif
#include <sndfile.h>
#include "common.h"
#include "wmnotify.h"
#include "sound.h"
#define BUFFER_LEN ((sf_count_t) 2048)
static int
OpenDspDevice( int channels, int srate )
{
int fd, status;
#if defined (__linux__)
int stereo, temp;
const char audio_device[] = "/dev/dsp";
#elif( defined(sun) && defined(unix) )
audio_info_t audio_info;
const char audio_device[] = "/dev/audio";
#endif
#if defined (__linux__)
fd = open( audio_device, O_WRONLY, 0 );
#elif( defined(sun) && defined(unix) )
/* Open the audio device - write only, non-blocking */
fd = open( audio_device, O_WRONLY | O_NONBLOCK );
#endif
if( fd < 0 ) {
fprintf( stderr, "%s: open() failed trying to open device '%s':\n", PACKAGE,
audio_device );
fprintf( stderr, " %s\n", strerror( errno ) );
fprintf( stderr,
" Check if device file exists and has correct write permissions.\n" );
ErrorLocation( __FILE__, __LINE__ );
return -1;
}
#if defined (__linux__)
stereo = 0;
status = ioctl( fd, SNDCTL_DSP_STEREO, &stereo );
if( status == -1 ) {
fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
status = ioctl( fd, SNDCTL_DSP_RESET, 0 );
if( status > 0 ) {
fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
temp = 16;
status = ioctl( fd, SOUND_PCM_WRITE_BITS, &temp );
if( status != 0 ) {
fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
status = ioctl( fd, SOUND_PCM_WRITE_CHANNELS, &channels );
if( status != 0 ) {
fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
status = ioctl( fd, SOUND_PCM_WRITE_RATE, &srate );
if( status != 0 ) {
fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
status = ioctl( fd, SNDCTL_DSP_SYNC, 0 );
if( status != 0 ) {
fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
#elif( defined(sun) && defined(unix) )
/* Retrieve standard values. */
AUDIO_INITINFO( &audio_info );
audio_info.play.sample_rate = sfinfo.samplerate;
audio_info.play.channels = sfinfo.channels;
audio_info.play.precision = 16;
audio_info.play.encoding = AUDIO_ENCODING_LINEAR;
audio_info.play.gain = AUDIO_MAX_GAIN;
audio_info.play.balance = AUDIO_MID_BALANCE;
status = ioctl( audio_fd, AUDIO_SETINFO, &audio_info );
if( status > 0 ) {
fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
#endif
return fd;
}
void
PlayAudioFile( char *filename, int volume )
{
static short buffer[BUFFER_LEN];
SNDFILE *sndfile;
SF_INFO sfinfo;
int audio_fd;
int readcount;
int status;
#if defined (__linux__)
int subformat;
int m;
#elif( defined(sun) && defined(unix) )
unsigned long delay_time;
long start_count, output_count, write_count;
bool done;
#endif
if( wmnotify_infos.debug ) {
printf( "%s: PlayAudioFile() Entry\n", PACKAGE );
}
if( filename == NULL ) {
fprintf( stderr, "%s: No audio file specified.\n", PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
sndfile = sf_open( filename, SFM_READ, &sfinfo );
if( sndfile == NULL ) {
fprintf( stderr, "%s: sf_open() failed trying to open '%s':\n", PACKAGE, filename );
fprintf( stderr, " %s\n", sf_strerror(NULL) );
fprintf( stderr, " Check if file exists and has correct read permissions.\n" );
ErrorLocation( __FILE__, __LINE__ );
return;
}
if( sfinfo.channels < 1 || sfinfo.channels > 2 ) {
fprintf( stderr, "%s: Audio file has %d channel(s), but ", PACKAGE, sfinfo.channels );
fprintf( stderr, "we support only 1 or 2 channels.\n" );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
audio_fd = OpenDspDevice( sfinfo.channels, sfinfo.samplerate );
if( audio_fd < 0 ) {
goto play_audio_file_close_file;
}
#if( defined(sun) && defined(unix) )
/* Delay time equal to 1/4 of a buffer in microseconds. */
delay_time = (BUFFER_LEN * 1000000) / (sfinfo.samplerate * 4);
#endif
subformat = sfinfo.format & SF_FORMAT_SUBMASK;
if( subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE ) {
static float flt_buffer[BUFFER_LEN];
double scale;
status = sf_command( sndfile, SFC_CALC_SIGNAL_MAX, &scale, (int) sizeof(scale) );
if( status == 0 ) {
fprintf( stderr, "%s: Warning, sf_command() failed.\n", PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
goto play_audio_file_close_audio;
}
if (scale < 1e-10) {
scale = 1.0;
}
else {
scale = 32700.0 / scale;
}
while( ( readcount = (int) sf_read_float( sndfile, flt_buffer, BUFFER_LEN ) ) != 0 ) {
/* Linux/OSS -- FLOAT samples */
#if defined (__linux__)
for( m = 0 ; m < readcount ; m++ ) {
/* Float to integer conversion. */
buffer[m] = (short) ( scale * flt_buffer[m] );
/* Changing volume */
buffer[m] = buffer[m] * volume / 100;
}
status = (int) write( audio_fd, buffer, readcount * sizeof(short) );
if( status == -1 ) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
goto play_audio_file_close_audio;
}
/* Solaris -- FLOAT samples */
#elif( defined(sun) && defined(unix) )
start_count = 0;
output_count = read_count * sizeof(short);
while( output_count > 0 ) {
/* Write as much data as possible */
for( m = 0 ; m < readcount ; m++ ) {
/* Float to integer conversion. */
buffer[m] = (short) ( scale * flt_buffer[m] );
/* Changing volume */
buffer[m] = buffer[m] * volume / 100;
}
write_count = write( audio_fd, &(buffer[start_count]), output_count );
if( write_count > 0 ) {
output_count -= write_count;
start_count += write_count;
}
else {
/* Give the audio output time to catch up. */
usleep( delay_time );
}
} /* while( output_count > 0 ) */
#endif
} /* while( ( readcount... ) */
}
else {
while( ( readcount = (int) sf_read_short( sndfile, buffer, BUFFER_LEN ) ) != 0 ) {
/* Linux/OSS -- INTEGER samples */
#if defined (__linux__)
/* Changing volume... */
for( m = 0 ; m < readcount ; m++ ) {
buffer[m] = ( buffer[m] * volume ) / 100;
}
status = (int) write( audio_fd, buffer, readcount * sizeof(short) );
if( status == -1 ) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
goto play_audio_file_close_audio;
}
/* Solaris -- INTEGER samples */
#elif( defined(sun) && defined(unix) )
start_count = 0;
output_count = read_count * sizeof(short);
while( output_count > 0 ) {
/* Write as much data as possible */
/* Changing volume. */
for( m = 0 ; m < read_count ; m++ ) {
buffer[m] = ( buffer[m] * volume ) / 100;
}
write_count = write( audio_fd, &(buffer[start_count]), output_count );
if( write_count > 0 ) {
output_count -= write_count;
start_count += write_count;
}
else {
/* Give the audio output time to catch up. */
usleep( delay_time );
}
} /* while( output_count > 0 ) */
#endif
} /* while( ( readcount... ) */
} /* else */
play_audio_file_close_audio:
status = close( audio_fd );
if( status != 0 ) {
fprintf( stderr, "%s: Error, close() failed.\n", PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
play_audio_file_close_file:
status = sf_close( sndfile );
if( status != 0 ) {
fprintf( stderr, "%s: Error, sf_close() failed.\n", PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
if( wmnotify_infos.debug ) {
printf( "%s: PlayAudioFile() Exit\n", PACKAGE );
}
return;
}
#endif /* HAVE_SNDFILE */

View file

@ -1,27 +0,0 @@
/*
* sound.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef SOUND_H
#define SOUND_H 1
void
PlayAudioFile(char *filename, int volume);
#endif /* SOUND_H */

View file

@ -1,115 +0,0 @@
/*
* ssl.c
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
* Based on ssl_client.c (Sean Walton and Macmillan Publishers).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#if HAVE_SSL
/* Define filename_M */
#define SSL_M 1
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "common.h"
#include "wmnotify.h"
#include "ssl.h"
/* InitCTX - initialize the SSL engine. */
SSL_CTX *
InitCTX( void )
{
SSL_METHOD *method;
SSL_CTX *ctx;
SSL_library_init(); /* Load cryptos, et.al. */
SSL_load_error_strings(); /* Bring in and register error messages */
method = SSLv23_client_method(); /* Indicate we support SSLv2, SSLv3 and TLSv1 methods. */
ctx = SSL_CTX_new(method); /* Create new context */
if( ctx == NULL ) {
ERR_print_errors_fp(stderr);
abort();
}
return ctx;
}
/* ShowCerts - print out the certificates. */
void
ShowCerts( SSL *ssl )
{
X509 *cert;
char *line;
cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
if ( cert != NULL ) {
printf("Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("Subject: %s\n", line);
free(line); /* free the malloc'ed string */
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("Issuer: %s\n", line);
free(line); /* free the malloc'ed string */
X509_free(cert); /* free the malloc'ed certificate copy */
}
else {
printf("No certificates.\n");
}
}
int
InitSSL( int sock_fd )
{
ssl_infos.ctx = InitCTX();
ssl_infos.ssl = SSL_new( ssl_infos.ctx ); /* create new SSL connection state */
if( ssl_infos.ssl == NULL ) {
printf( "%s: Error in SSL_new()\n", PACKAGE );
return EXIT_FAILURE;
}
SSL_set_fd( ssl_infos.ssl, sock_fd ); /* attach the socket descriptor */
if( SSL_connect( ssl_infos.ssl ) == FAIL ) { /* perform the connection */
ERR_print_errors_fp(stderr);
return EXIT_FAILURE;
}
if( wmnotify_infos.debug ) {
printf("Connected with %s encryption\n", SSL_get_cipher( ssl_infos.ssl ));
ShowCerts( ssl_infos.ssl ); /* get any certs */
}
return EXIT_SUCCESS;
}
#endif /* HAVE_SSL */

View file

@ -1,61 +0,0 @@
/*
* ssl.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef SSL_H
#define SSL_H 1
#if HAVE_CONFIG_H
# include "config.h"
#endif
#if HAVE_SSL
#include <openssl/ssl.h>
#include <openssl/err.h>
/* Exported variables */
#undef _SCOPE_
#ifdef SSL_M
# define _SCOPE_ /**/
#else
# define _SCOPE_ extern
#endif
#define FAIL -1
typedef struct ssl_infos_t {
SSL_CTX *ctx;
SSL *ssl;
} ssl_infos_t;
_SCOPE_ ssl_infos_t ssl_infos;
SSL_CTX *
InitCTX( void );
void
ShowCerts( SSL *ssl );
int
InitSSL( int sock_fd );
#endif /* HAVE_SSL */
#endif /* SSL_H */

View file

@ -1,468 +0,0 @@
/*
* wmnotify.c -- POP3 E-mail notification program
*
* Copyright (C) 2003 Hugo Villeneuve (hugo@hugovil.com)
* based on WMPop3 by Scott Holden (scotth@thezone.net)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Define filename_M */
#define WMNOTIFY_M 1
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <assert.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "common.h"
#include "dockapp.h"
#include "pop3.h"
#include "imap.h"
#include "network.h"
#include "xevents.h"
#include "options.h"
#include "configfile.h"
#if defined(HAVE_SNDFILE)
# include "sound.h"
#endif
#include "wmnotify.xpm"
#include "wmnotify.h"
/* Set in DoubleClick() to stop the new mail animation when the mail client is
opened. */
static bool animation_stop = false;
static int animation_image = MAILBOX_FULL;
/* Set in response to signal sent by SingleClick() to force mail check. Also set to true at
* startup to force initial check. */
static bool manual_check = true;
/* Used to signal TimerThread to quit. Inactive for now. */
static bool quit = false;
static int double_click_notif = false;
/* TimerThread ID */
static pthread_t timer_thread;
inline void
ErrorLocation( const char *file, int line )
{
fprintf( stderr, " Error in file \"%s\" at line #%d\n", file, line );
}
void *
xmalloc( size_t size, const char *filename, int line_number )
{
void *value;
value = malloc( size );
if( value == NULL ) {
perror( PACKAGE );
ErrorLocation( filename, line_number );
exit( EXIT_FAILURE );
}
return value;
}
static void
DisplayOpenedEmptyMailbox( void )
{
/* Opened and empty mailbox image */
copyXPMArea( MAILBOX_OPENED_EMPTY_SRC_X, MAILBOX_OPENED_EMPTY_SRC_Y,
MAILBOX_SIZE_X, MAILBOX_SIZE_Y, MAILBOX_DEST_X, MAILBOX_DEST_Y );
RedrawWindow();
}
static void
DisplayOpenedFullMailbox( void )
{
/* Full mailbox image */
copyXPMArea( MAILBOX_OPENED_FULL_SRC_X, MAILBOX_OPENED_FULL_SRC_Y,
MAILBOX_SIZE_X, MAILBOX_SIZE_Y,
MAILBOX_DEST_X, MAILBOX_DEST_Y );
RedrawWindow();
}
static void
DisplayClosedMailbox( void )
{
/* Opened mailbox image */
copyXPMArea( MAILBOX_CLOSED_SRC_X, MAILBOX_CLOSED_SRC_Y,
MAILBOX_SIZE_X, MAILBOX_SIZE_Y,
MAILBOX_DEST_X, MAILBOX_DEST_Y );
RedrawWindow();
}
static void
DisplayExecuteCommandNotification( void )
{
/* Visual notification that the double-click was catched. */
copyXPMArea( EXEC_CMD_IMG_SRC_X, EXEC_CMD_IMG_SRC_Y,
MAILBOX_SIZE_X, MAILBOX_SIZE_Y, MAILBOX_DEST_X, MAILBOX_DEST_Y );
RedrawWindow();
}
static void
ExecuteCommand( char *argv[] )
{
pid_t pid;
char *msg;
/* No command defined, this is not an error. */
if( argv[0] == NULL ) {
return;
}
pid = fork(); /* fork a child process. */
if( pid < 0) {
perror( PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
else if( pid == 0 ) { /* Child process */
/* When execvp() is successful, it doesn't return; otherwise, it returns
-1 and sets errno. */
(void) execvp( argv[0], argv );
msg = strerror( errno );
fprintf( stderr, "%s: The external mail program couldn't be started.\n",
PACKAGE);
fprintf( stderr, "Check your path or your configuration file for errors.\n"
);
fprintf( stderr, "%s: \"%s\"\n", msg, argv[0] );
exit( EXIT_FAILURE );
}
}
/* single-click --> Checking mail */
static void
SingleClick( void )
{
int status;
if( wmnotify_infos.debug ) {
printf( "%s: SingleClick() Entry\n", PACKAGE );
}
/* Sending a signal to awake the TimerThread() thread. */
status = pthread_kill( timer_thread, SIGUSR1 );
if( status != EXIT_SUCCESS ) {
fprintf( stderr, "%s: pthread_kill() error (%d)\n", PACKAGE, status );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
if( wmnotify_infos.debug ) {
printf( "%s: SingleClick() Exit\n", PACKAGE );
}
}
/* Double-click --> Starting external mail client. */
static void
DoubleClick( void )
{
int status;
if( wmnotify_infos.mail_client_argv[0] != NULL ) {
/* Starting external mail client. */
ExecuteCommand( wmnotify_infos.mail_client_argv );
double_click_notif = true;
/* Sending a signal to awake the TimerThread() thread. This was previously
done with a mutex variable (animation_stop), but this caused a bug when the
following sequence was encountered:
-The user double-click to start the external mail client
-A new E-mail is received shortly after that
-The user exit the external mail client
-The user manually check for new E-mail
-The audio notification sound is played, but no animation image is
displayed.
This was because setting the mutex variable 'animation_stop' didn't
awakened the TimerThread(), but single-clicking awakened it. Since the
'animation_stop' variable was still set to true, no animation occured. */
status = pthread_kill( timer_thread, SIGUSR2 );
if( status != EXIT_SUCCESS ) {
fprintf( stderr, "%s: pthread_kill() error (%d)\n", PACKAGE, status );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
DisplayExecuteCommandNotification();
sleep(1);
DisplayClosedMailbox();
double_click_notif = false;
}
else {
fprintf( stderr, "%s: Warning: No email-client defined.\n", PACKAGE );
}
}
static void
CatchChildTerminationSignal( int signal )
{
switch( signal ) {
case SIGCHLD:
/* Wait for Mail Client child process termination. Child enters zombie
state: process is dead and most resources are released, but process
descriptor remains until parent reaps exit status via wait. */
/* The WNOHANG option prevents the call to waitpid from suspending execution
of the caller. */
(void) waitpid( 0, NULL, WNOHANG );
break;
default:
fprintf( stderr, "%s: Unregistered signal received, exiting.\n", PACKAGE );
exit( EXIT_FAILURE );
}
}
static void
CatchTimerSignal( int signal )
{
switch( signal ) {
case SIGUSR1:
/* Catching the signal sent by the SingleClick() function. */
manual_check = true;
break;
case SIGUSR2:
/* Catching the signal sent by the DoubleClick() function. */
animation_stop = true;
break;
default:
fprintf( stderr, "%s: CatchTimerSignal(): unknown signal (%d)\n", PACKAGE,
signal );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
}
static void
NewMailAnimation( void )
{
if( animation_image == MAILBOX_FULL ) {
DisplayOpenedFullMailbox();
animation_image = MAILBOX_CLOSED;
if( wmnotify_infos.debug ) {
printf( "%s: NewMailAnimation() MAILBOX_FULL.\n", PACKAGE );
}
}
else {
DisplayClosedMailbox();
animation_image = MAILBOX_FULL;
if( wmnotify_infos.debug ) {
printf( "%s: NewMailAnimation() MAILBOX_CLOSED.\n", PACKAGE );
}
}
}
/* We display the opened mailbox image only when doing a manual check. */
static int
CheckForNewMail( bool manual_check )
{
int new_messages;
if( manual_check == true ) {
DisplayOpenedEmptyMailbox();
}
if( wmnotify_infos.protocol == POP3_PROTOCOL ) {
new_messages = POP3_CheckForNewMail();
}
else if( wmnotify_infos.protocol == IMAP4_PROTOCOL ) {
new_messages = IMAP4_CheckForNewMail();
}
else {
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
if( ( manual_check == true ) && ( new_messages > 0 ) ) {
animation_image = MAILBOX_FULL;
}
return new_messages;
}
static void *
TimerThread( /*@unused@*/ void *arg )
{
int new_messages = 0;
int counter = -1;
bool animation_running = false;
/* For catching the signal SIGUSR1. This signal is sent by the main program thread when the
* user is issuing a single-click to manually check for new mails. */
(void) signal( SIGUSR1, CatchTimerSignal );
/* For catching the signal SIGUSR2. This signal is sent by the main program thread when the
* user is issuing a double-click to start ther external mail client. */
(void) signal( SIGUSR2, CatchTimerSignal );
while( quit == false ) {
if( wmnotify_infos.debug ) {
printf( "%s: Timer thread iteration.\n", PACKAGE );
}
if( ( manual_check == true ) || ( counter == 0 ) ) {
new_messages = CheckForNewMail( manual_check );
manual_check = false;
if( wmnotify_infos.debug ) {
printf( "%s: new messages = %d.\n", PACKAGE, new_messages );
}
if( new_messages > 0 ) {
/* Checking if audio notification was already produced. */
if( animation_running == false ) {
/* Audible notification, if requested in configuration file. */
if( wmnotify_infos.audible_notification != false ) {
if( strlen( wmnotify_infos.audiofile ) != 0 ) {
#if defined(HAVE_SNDFILE)
PlayAudioFile( wmnotify_infos.audiofile, wmnotify_infos.volume );
#endif
}
else {
AudibleBeep();
}
}
animation_running = true;
}
/* Number of times to execute timer loop before checking again for new mails when the
* animation is running (when the animation is running, we sleep for
* NEW_MAIL_ANIMATION_DURATION instead of wmnotify_infos.mail_check_interval). We set
* the check interval to 30 seconds because we want the new mail condition to be
* removed as soon as possible when the new messages are checked. */
counter = 30 * 1000000 / NEW_MAIL_ANIMATION_DURATION;
}
}
if( ( animation_stop == true ) || ( new_messages <= 0 ) ) {
if( wmnotify_infos.debug ) {
if( animation_stop != false ) {
printf( "%s: animation_stop is true\n", PACKAGE );
}
}
animation_running = false;
animation_stop = false;
if( double_click_notif == false ) {
/* Before exiting, be sure to put NO MAIL image back in place... */
DisplayClosedMailbox();
}
}
/* If sleep() returns because the requested time has elapsed, the value returned will be
* 0. If sleep() returns because of premature arousal due to delivery of a signal, the
* return value will be the "unslept" amount (the requested time minus the time actually
* slept) in seconds. */
if( animation_running == false ) {
(void) sleep( wmnotify_infos.mail_check_interval );
counter = 0;
}
else {
NewMailAnimation();
(void) usleep( NEW_MAIL_ANIMATION_DURATION );
counter--;
}
if( wmnotify_infos.debug ) {
printf( "%s: counter = %d\n", PACKAGE, counter );
}
} /* end while */
if( wmnotify_infos.debug ) {
printf( "%s: Error, TimerThread() exited abnormally\n", PACKAGE );
}
/* This code is never reached for now, because quit is always false. */
pthread_exit( NULL );
}
/*******************************************************************************
* Main function
******************************************************************************/
int
main( int argc, char *argv[] )
{
int status;
/* Initialization */
ParseCommandLineOptions( argc, argv );
/* Reading configuration options from configuration file. */
ConfigurationFileInit();
/* For catching the termination signal SIGCHLD when the external mail client
program is terminated, thus permitting removing zombi processes... */
(void) signal( SIGCHLD, CatchChildTerminationSignal );
/* Initialize callback function pointers. */
ProcessXlibEventsInit( SingleClick, DoubleClick );
/* Initializing and creating a DockApp window. */
InitDockAppWindow( argc, argv, wmnotify_xpm, wmnotify_infos.display_arg,
wmnotify_infos.geometry_arg );
/* Starting thread for periodically checking for new mail. */
status = pthread_create( &timer_thread, NULL, TimerThread, NULL );
if( status != 0 ) {
fprintf( stderr, "%s: Thread creation failed (%d)\n", PACKAGE, status );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
/* Main loop, processing X Events */
ProcessXlibEvents();
/* This code is never reached for now. */
fprintf( stderr, "%s: Program exit\n", PACKAGE );
exit( EXIT_SUCCESS );
}

View file

@ -1,95 +0,0 @@
/*
* wmnotify.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef WMNOTIFY_H
#define WMNOTIFY_H 1
#define POP3_PROTOCOL 0
#define IMAP4_PROTOCOL 1
/* New messages animation duration, in microseconds. */
#define NEW_MAIL_ANIMATION_DURATION 900000
/* Flag used in the new messages animation to identify which image is currently
displayed. */
#define MAILBOX_CLOSED 0
#define MAILBOX_FULL 1
/* Source coordinates in global pixmap for the closed mailbox image. */
#define MAILBOX_CLOSED_SRC_X 64
#define MAILBOX_CLOSED_SRC_Y 4
/* Source coordinates in global pixmap for the opened and empty mailbox image. */
#define MAILBOX_OPENED_EMPTY_SRC_X 64
#define MAILBOX_OPENED_EMPTY_SRC_Y 64
/* Source coordinates in global pixmap for the opened and full mailbox image. */
#define MAILBOX_OPENED_FULL_SRC_X 4
#define MAILBOX_OPENED_FULL_SRC_Y 64
/* Source coordinates in global pixmap for the opened and full mailbox image. */
#define EXEC_CMD_IMG_SRC_X 124
#define EXEC_CMD_IMG_SRC_Y 4
/* Size of all mailbox images. */
#define MAILBOX_SIZE_X 56
#define MAILBOX_SIZE_Y 56
/* Destination coordinates when copying a mailbox image. */
#define MAILBOX_DEST_X 4
#define MAILBOX_DEST_Y 4
#define ARGV_LIMIT 64
#define MAX_STR_LEN 256
typedef struct wmnotify_t
{
bool debug;
char *display_arg;
char *geometry_arg;
char *optional_config_file;
char mail_client_command[512];
char *mail_client_argv[ARGV_LIMIT];
unsigned int mail_check_interval; /* In seconds. */
bool audible_notification;
char audiofile[512];
int volume;
int protocol;
char imap_folder[MAX_STR_LEN];
bool use_ssl;
char server_name[MAX_STR_LEN];
int port;
char username[MAX_STR_LEN];
char password[MAX_STR_LEN];
int sock_fd;
} wmnotify_t;
/* Exported variables */
#undef _SCOPE_
#ifdef WMNOTIFY_M
# define _SCOPE_ /**/
#else
# define _SCOPE_ extern
#endif
_SCOPE_ wmnotify_t wmnotify_infos;
#endif /* WMNOTIFY_H */

View file

@ -1,148 +0,0 @@
/*
* xevents.c -- handling X events, and detecting single-click and double-click
* mouse events.
*
* Copyright (C) 2009 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <sys/types.h>
#include <X11/Xlib.h>
#include "common.h"
#include "dockapp.h"
#include "xevents.h"
/* Maximum time between mouse double-clicks, in milliseconds */
#define DOUBLE_CLICK_MAX_INTERVAL_MS 250
/* Function pointers to handle single and double mouse click events. */
static void (*SingleClickCallback)( void ) = NULL;
static void (*DoubleClickCallback)( void ) = NULL;
void
AudibleBeep( void )
{
/* The specified volume is relative to the base volume for the keyboard.
To change the base volume of the keyboard, use XChangeKeyboardControl(). */
(void) XBell( dockapp.display, 100 ); /* Volume = 100% */
}
/* This function must be called at the beginning of your program to initialize
the function pointers to handle single and double click mouse events. */
void
ProcessXlibEventsInit( void (*single_click_callback)( void ),
void (*double_click_callback)( void ) )
{
int status;
/* This must be called before any other XLib functions. */
status = XInitThreads();
if( status == 0 ) {
fprintf( stderr, "%s: XInitThreads() initialization failed\n", PACKAGE );
ErrorLocation( __FILE__, __LINE__ );
exit( EXIT_FAILURE );
}
SingleClickCallback = single_click_callback;
DoubleClickCallback = double_click_callback;
}
/* Processing of X events */
void
ProcessXlibEvents( void )
{
bool quit = false;
bool button1_pressed = false;
bool check_for_double_click = false;
XEvent Event;
while( quit == false ) {
if( ( check_for_double_click != false ) &&
( XPending( dockapp.display ) == 0 ) ) {
/* If no other button 1 events are received after the delay, then it is a
single-click mouse event. */
if( SingleClickCallback != NULL ) {
(*SingleClickCallback)();
}
check_for_double_click = false;
}
/* XNextEvent is a blocking call: it will return only when an event is
ready to be processed, thus freeing the CPU for other tasks when no
events are available. */
(void) XNextEvent( dockapp.display, &Event );
switch( Event.type ) {
case Expose:
/* Window was uncovered... */
RedrawWindow();
break;
case DestroyNotify:
/* Window was killed... */
/* Is this necessary ? */
(void) XCloseDisplay( dockapp.display );
quit = true;
break;
case ClientMessage:
/* Doesn't seem to work... */
printf( "Client message received...\n" );
break;
case ButtonPress:
if( Event.xbutton.button == Button1 ) {
/* Mouse LEFT button pressed. */
button1_pressed = true;
}
break;
case ButtonRelease:
if( Event.xbutton.button == Button1 ) {
/* Mouse LEFT button released. */
if( button1_pressed != false ) {
/* We act only when the button is released */
if( check_for_double_click != false ) {
/* Double-click */
if( DoubleClickCallback != NULL ) {
(*DoubleClickCallback)();
}
check_for_double_click = false;
}
else {
(void) usleep( DOUBLE_CLICK_MAX_INTERVAL_MS * 1000 );
check_for_double_click = true;
}
}
}
break;
}
} /* end while */
}

View file

@ -1,34 +0,0 @@
/*
* xevents.h
*
* Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef XEVENTS_H
#define XEVENTS_H 1
void
AudibleBeep(void);
void
ProcessXlibEventsInit(void (*single_click_callback)(void),
void (*double_click_callback)(void));
void
ProcessXlibEvents(void);
#endif /* XEVENTS_H */