summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Lemmen <robertle@semistable.com>2005-10-02 16:55:03 +0200
committerRobert Lemmen <robertle@semistable.com>2005-10-02 16:55:03 +0200
commit506c0631ef00a77295dfcb885a2dd85ebd083e0d (patch)
treeb1429d6834a665fb8b813dd7d39ca652448dd303
Import aewan_1.0.01.orig.tar.gz
[dgit import orig aewan_1.0.01.orig.tar.gz]
-rw-r--r--CHANGELOG37
-rw-r--r--COPYING341
-rw-r--r--Makefile.in85
-rw-r--r--README77
-rw-r--r--TODO30
-rw-r--r--absmenu.c115
-rw-r--r--absmenu.h116
-rw-r--r--aecat.c275
-rw-r--r--aeff.c349
-rw-r--r--aeff.h104
-rw-r--r--aemakeflic.c249
-rw-r--r--aewan.c218
-rw-r--r--aewl/aewl.c44
-rw-r--r--aewl/aewl.h69
-rw-r--r--aewl/allwidgets.h42
-rw-r--r--aewl/button.c96
-rw-r--r--aewl/button.h65
-rw-r--r--aewl/field.c180
-rw-r--r--aewl/field.h69
-rw-r--r--aewl/form.c133
-rw-r--r--aewl/form.h97
-rw-r--r--aewl/form_int.h17
-rw-r--r--aewl/label.c104
-rw-r--r--aewl/label.h68
-rw-r--r--aewl/listbox.c200
-rw-r--r--aewl/listbox.h95
-rw-r--r--aewl/util.c128
-rw-r--r--aewl/util.h76
-rw-r--r--aewl/widget.c48
-rw-r--r--aewl/widget.h86
-rw-r--r--bores/Makefile64
-rw-r--r--bores/autod.c58
-rw-r--r--bores/autod.h122
-rw-r--r--bores/bores.h38
-rw-r--r--bores/darray.c137
-rw-r--r--bores/darray.h95
-rw-r--r--bores/defs.h43
-rw-r--r--bores/hashdict.c222
-rw-r--r--bores/hashdict.h139
-rw-r--r--bores/kurses.c293
-rw-r--r--bores/kurses.h133
-rw-r--r--bores/util.c270
-rw-r--r--bores/util.h169
-rw-r--r--chtr.c61
-rw-r--r--chtr.h67
-rw-r--r--clipboard.c70
-rw-r--r--clipboard.h52
-rw-r--r--colordlg.c96
-rw-r--r--colordlg.h44
-rw-r--r--commands.h83
-rwxr-xr-xconfigure4558
-rw-r--r--configure.ac42
-rw-r--r--debug_aewl.c121
-rw-r--r--debug_aewl.h7
-rw-r--r--document.c227
-rw-r--r--document.h108
-rw-r--r--editmeta.c123
-rw-r--r--editmeta.h41
-rw-r--r--export.c86
-rw-r--r--export.h74
-rw-r--r--filedlg.c319
-rw-r--r--filedlg.h49
-rw-r--r--handlekey.c624
-rw-r--r--handlekey.h50
-rw-r--r--helpdlg.c127
-rw-r--r--helpdlg.h42
-rw-r--r--init_aewl.c79
-rw-r--r--init_aewl.h42
-rw-r--r--keybind.c97
-rw-r--r--keybind.h50
-rw-r--r--keys.c64
-rw-r--r--keys.h99
-rw-r--r--layer.c314
-rw-r--r--layer.h144
-rw-r--r--layerdlg.c168
-rw-r--r--layerdlg.h45
-rw-r--r--make-package.sh23
-rw-r--r--man/man1/aecat.163
-rw-r--r--man/man1/aemakeflic.150
-rw-r--r--man/man1/aewan.150
-rw-r--r--man/man5/aewan.5108
-rw-r--r--menubar-items.inc77
-rw-r--r--menubar.c228
-rw-r--r--menubar.h51
-rw-r--r--psd.c82
-rw-r--r--psd.h98
-rw-r--r--python/NOTICE6
-rw-r--r--python/aewan.py185
-rw-r--r--python/test.py54
-rw-r--r--ui.c141
-rw-r--r--ui.h80
-rw-r--r--version.h41
-rw-r--r--vlayer.c48
-rw-r--r--vlayer.h80
-rw-r--r--welcomedlg.c130
-rw-r--r--welcomedlg.h42
96 files changed, 15206 insertions, 0 deletions
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..50d1b6b
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,37 @@
+1.0.01
+
+ * aecat now accepts "comment" format (which extracts metadata from the file)
+ and -L option (which outputs layer count) - contributed by
+ Gerfried Fuchs (alfie@ist.org)
+ * corrected aeff (aewan file format) escape sequence interpretation bug
+ that was causing special characters in metainfo to get garbled
+ * added "resize layer" funcionality, also contributed by
+ Gerfried Fuchs (alfie@ist.org)
+ * both 'Load file' and 'Save file' now use dialog boxes that let the
+ user browse directories
+ * added a new export utility: aemakeflic, which converts aewan documents
+ into animations to be played in the 'less' command or as a shell script
+ * added a confirmation question when quitting the program or clearing
+ the document to prevent against accidental loss of current work
+ * in the version number, the revision will be conventionally written
+ with two digits from now on
+
+0.9.7
+
+ * cleaned up Makefile.in to make the bores/ directory (remnants of a library
+ that used to be separate from aewan) compile together with the rest
+ of the project instead of separately as libbores.a
+
+0.9.6 - release date: 2005-02-19 (minor bugfix release)
+
+ * fixed segfault bug which resulted from trying to correct cursor coords
+ when a layer had just been added (reported in Debian bug tracking system)
+
+0.9.5 - release date: 2005-02-18
+
+ * menu introduced in order to make the interface more friendly
+ * "new file" (i.e. clear everything and start from scratch) funcionality added
+ * added patches from Gerfried Fuchs (alfie@ist.org):
+ - aecat now produces more XHTML-compliant html and supports
+ background color
+ - user can now manipulate upper-left corner of selection in select mode
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..525c524
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,341 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: 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) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..5aac058
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,85 @@
+# Copyright (c) 2003 Bruno T. C. de Oliveira
+#
+# LICENSE INFORMATION:
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Copyright (c) 2002 Bruno T. C. de Oliveira
+#
+# INFORMAÇÕES DE LICENÇA:
+# Este programa é um software de livre distribuição; você pode
+# redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+# Public License, conforme publicado pela Free Software Foundation,
+# pela versão 2 da licença ou qualquer versão posterior.
+#
+# Este programa é distribuído na esperança de que ele será útil
+# aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+# a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+# QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+# License para obter mais detalhes (uma cópia acompanha este
+# programa, armazenada no arquivo COPYING).
+
+sources=$(wildcard *.c) $(wildcard aewl/*.c) $(wildcard bores/*.c)
+headers=$(wildcard *.h) $(wildcard bores/*.h) $(wildcard aewl/*.h)
+execs=aewan@EXESUF@ aecat@EXESUF@ aemakeflic@EXESUF@
+mainobjs=$(patsubst %@EXESUF@,%.o,$(execs))
+objects=$(filter-out $(mainobjs), $(patsubst %.c,%.o,$(sources)))
+
+CC=@CC@
+CFLAGS=@CFLAGS@ -fno-strict-aliasing -Wall
+LIBS=@LIBS@
+LDFLAGS=@LDFLAGS@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+bindir=@bindir@
+mandir=@mandir@
+
+export CC
+export CFLAGS
+export LDFLAGS
+export LIBS
+
+all: $(execs)
+
+$(execs): %@EXESUF@: %.o $(objects)
+ $(CC) $(CFLAGS) -o $@ $(objects) \
+ $(patsubst %@EXESUF@, %.o, $@) $(LDFLAGS) $(LIBS)
+
+clean:
+ rm -f *.o aewl/*.o bores/*.o depends aewan.log $(execs) *.stackdump
+
+distclean: clean
+ rm -rf autom4te.cache config.status config.log Makefile
+
+cvsclean: distclean
+ rm -f configure
+
+install: all
+ mkdir -p $(DESTDIR)$(bindir)
+ cp $(execs) $(DESTDIR)$(bindir)
+ mkdir -p $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir)/man5
+ cp man/man1/*.1 $(DESTDIR)$(mandir)/man1
+ cp man/man5/*.5 $(DESTDIR)$(mandir)/man5
+
+-include depends
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
+depends: $(sources) $(headers)
+ $(CC) $(CFLAGS) -MM $(sources) >depends
+
+.PHONY: clean all depends
+
diff --git a/README b/README
new file mode 100644
index 0000000..75f820d
--- /dev/null
+++ b/README
@@ -0,0 +1,77 @@
+AEWAN Ascii Art Editor
+Copyright (c) 2004 Bruno Takahashi C. de Oliveira
+Licensed under the GNU General Public license
+Refer to the COPYING file for a full text of the license.
+
+[[ 0. PROJECT HOME PAGE ]]
+
+ http://aewan.sourceforge.net
+
+There you will find author information, FAQ, links to the latest
+version of the program, etc.
+
+[[ 1. HOW TO COMPILE AND INSTALL ]]
+
+Assuming you downloaded aewan-0.X.Y.tar.gz (where X, Y represent nonnegative
+integers), this is how you would compile it:
+
+$ tar -zxf aewan-0.X.Y.tar.gz
+$ cd aewan-0.X.Y
+$ ./configure
+$ make
+$ su -c 'make install'
+
+NOTE: as of version 0.8.7, aewan no longer requires the separate libbores
+library, since it has been merged into the project.
+
+[[ 2. THANKS ]]
+
+Thanks to every who, directly or indirectly, contributed to this project.
+In particular, I would like to thank:
+
+ * Sourceforge.net for their excellent Open Source hosting infrastructure
+ * The authors of tetradraw, whose program served as an inspiration
+ to write this editor
+
+I would also like to thank Robert Lemmen <robertle@semistable.com> for all
+his cooperation in getting aewan into the Debian distribution.
+
+PEOPLE WHO HAVE WORKED OR ARE CURRENTLY WORKING ON THIS PROJECT:
+
+ * Bruno T. C. de Oliveira (brunotc@gmail.com)
+ * Peep Pullerits (http://solicit.estprog.ee; solicit@estprog.ee)
+ * Praveen Kurup <praveen_kurup@jasubhai.com>
+ * Gerfried Fuchs <alfie@ist.org>
+
+[[ 3. WHAT IS AEWAN ]]
+
+Summary: Aewan is a multi-layered ascii-art/animation editor that produces
+both stand-alone cat-able art files and an easy-to-parse format for integration
+in your terminal applications. It is primarily designed for Linux, although it
+currently also compiles under FreeBSD and possibly other *NIX systems.
+
+More details: Aewan is a curses-based program that allows for the creation and
+editing of ascii art. The user is able to move the cursor around the screen by
+means of the arrow keys and 'paint' characters by pressing the corresponding
+keys. There are dialog boxes that allow the user to choose foreground and
+background colors, as well as bold and blink attributes. The user may also
+select rectangular areas of the canvas in order to move, copy and paste them.
+Aewan also supports 'intelligent' horizontal and vertical flipping (e.g.
+converts '\' to '/', etc).
+
+What sets Aewan apart from similar projects is the fact that it can work with
+multiple layers, and has the ability to turn transparency and visibility on and
+off for each layer. A layer dialog is provided through which the user can
+change the order of the layers. Thus, each layer can be edited independently in
+order to generate a composite drawing. Instead of using the layers for
+compositing, it is also possible to use the layers as frames for an animation,
+thus enabling the user to create ascii animations with Aewan (note: to be fully
+implemented next release).
+
+The file format is easy to parse, so it is easy to write a terminal-based
+application that uses the Aewan files to display onscreen. Currently it has
+been tested on the Linux terminal, rxvt, xterm, the Cygwin terminal and the
+FreeBSD console. Although it is already quite stable (I am already using it on
+some projects of mine), it is a little rough on the edges, but that can be
+worked out in the near future.
+
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..9b9e430
--- /dev/null
+++ b/TODO
@@ -0,0 +1,30 @@
+TODO
+Items in order of importance
+
+CURRENT WORK
+
+- see TODO in filedlg.c
+
+CORRECTIONS:
+
+- [aewl] make the label widget a little more robust: make it respect its width
+ when painting itself
+
+- [aewl] make text fields 'scrollable'
+
+- [aewl] BUG: cursor in textfield goes arbitrarily to the right as text
+ is added beyond the visible part of it
+
+NEW FEATURES:
+
+- dialogs!!!! For saving files, opening files, confirming operations,
+ specifying layer dimensions, renaming layers and everything else
+- IMPORT/EXPORT from/to ansi, etc
+
+- flip strategies (let user decide what characters are to be flipped)
+- more intuitive transparent-layer handling (or add more documentation)
+- enable smaller layers to be placed anywhere instead of always having
+ to be anchored to the top-left corner
+
+- configurable key bindings
+
diff --git a/absmenu.c b/absmenu.c
new file mode 100644
index 0000000..15b1679
--- /dev/null
+++ b/absmenu.c
@@ -0,0 +1,115 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+#include <ncurses.h>
+#include <stdlib.h>
+
+#include "absmenu.h"
+
+AbsMenu *menu_create(int *ic, int x0, int y0, int w, int h,
+ int attr_sel, int attr_unsel,
+ void (*painter)(int, struct _AbsMenu *))
+{
+ AbsMenu *new_menu = zalloc(sizeof(struct _AbsMenu));
+ new_menu->item_count = ic ? ic : &(new_menu->__ic);
+ new_menu->x0 = x0;
+ new_menu->y0 = y0;
+ new_menu->w = w;
+ new_menu->h = h;
+ new_menu->attr_sel = attr_sel;
+ new_menu->attr_unsel = attr_unsel;
+ new_menu->painter = painter;
+ return new_menu;
+}
+
+void menu_destroy(AbsMenu *m) {
+ if (m) free(m);
+}
+
+void menu_set_count(AbsMenu *m, int i) {
+ m->__ic = i;
+}
+
+int menu_get_count(AbsMenu *m) {
+ return *(m->item_count);
+}
+
+void menu_paint(AbsMenu *m) {
+ int i; int index; int j;
+ int sely = m->y0;
+ for (i = 0; i < m->h; i++) {
+ index = i + m->item_at_top;
+ if (index == m->sel_item) sely = m->y0 + i;
+
+ kurses_move(m->x0, m->y0 + i);
+ kurses_color_at((m->sel_item == index) ? m->attr_sel : m->attr_unsel);
+ for (j = 0; j < m->w; j++) addch(' ');
+
+ kurses_move(m->x0, m->y0 + i);
+ if (index >= 0 && index < *(m->item_count)) (*m->painter)(index, m);
+ }
+
+ /* place cursor on currently selected item */
+ kurses_move(m->x0, sely);
+}
+
+static void menu_correct(AbsMenu *m) {
+ /* corrige m->sel_item */
+ while (m->sel_item < 0) m->sel_item = 0;
+ while (m->sel_item >= *(m->item_count)) m->sel_item = -1 + *(m->item_count);
+
+ /* corrige m->item_at_top de forma que o item selecionado
+ * seja visível */
+ if (m->item_at_top > m->sel_item)
+ m->item_at_top = m->sel_item;
+ else if (m->sel_item >= m->item_at_top + m->h)
+ m->item_at_top = m->sel_item - m->h + 1;
+}
+
+void menu_handle_key(AbsMenu *m, int ch) {
+ switch (ch) {
+ case KEY_UP: m->sel_item--; break;
+ case KEY_DOWN: m->sel_item++; break;
+ case KEY_NPAGE: m->sel_item += m->h; break;
+ case KEY_PPAGE: m->sel_item -= m->h; break;
+ }
+
+ menu_correct(m);
+}
+
+void menu_select_item(AbsMenu *m, int i) {
+ m->sel_item = i;
+ menu_correct(m);
+}
+
diff --git a/absmenu.h b/absmenu.h
new file mode 100644
index 0000000..907b68a
--- /dev/null
+++ b/absmenu.h
@@ -0,0 +1,116 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+/* absmenu.h - an abstract menu that lets creator specify a paint function,
+ * and even the address of an item count */
+
+#ifndef _btco_aewan_abmenu_h
+#define _btco_aewan_abmenu_h
+
+struct _AbsMenu {
+ int __ic; /* itemcount variable, if the caller chose to use
+ * nondynamic count */
+ int *item_count; /* pointer to item count variable. If the caller chose
+ * nondynamic count, this points to __ic. Can never be
+ * NULL. */
+ int x0, y0; /* rendering position onscreen */
+ int w, h; /* dimensions of renderable area */
+
+ int attr_sel, attr_unsel; /* color attributes for selected and
+ unselected items */
+
+ int item_at_top; /* which item index is currently being drawn at
+ * the top of the menu. This defines the scrolling
+ * position of the menu. If *item_count > 0,
+ * this must be a value such that
+ * 0 <= item_at_top < *item_count */
+
+ int sel_item; /* the selected item in the menu. If *item_count > 0,
+ * this must be a value such that
+ * 0 <= sel_item < *item_count */
+
+ void (*painter)(int i, struct _AbsMenu *menu);
+ /* painter function that paints menu
+ entry index i */
+};
+typedef struct _AbsMenu AbsMenu;
+
+/* Create a new abstract menu.
+ * ic - address of a variable that will serve as the menu's item count.
+ * Pass NULL to use an internally maintained count that can be
+ * manipulated with menu_set_count and menu_get_count.
+ *
+ * x0, y0, w, h - a rectangle that indicates the area of the screen to which
+ * the menu should be rendered
+ *
+ * attr_sel, attr_unsel - color attributes to use for selected
+ * entries and unselected entries. The lowest four bits of an attribute
+ * is the background color, the next four bits indicate the foreground
+ * color.
+ *
+ * painter - the address of a function that will be called in order to
+ * paint the menu items. The cursor will be appropriately placed
+ * before the function call, and the whole line will already have
+ * been filled with the appropriate color; also, the appropriate
+ * color will already be set. The function also receives a pointer
+ * to the menu itself for convenience.
+ */
+AbsMenu *menu_create(int *ic, int x0, int y0, int w, int h,
+ int attr_sel, int attr_unsel,
+ void (*painter)(int, struct _AbsMenu *));
+
+/* Destroys a menu previously created with menu_create */
+void menu_destroy(AbsMenu *m);
+
+/* Set the item count for menu m. This can only be used if NULL was
+ * passed as the <ic> parameter of menu_create when the menu was
+ * created. */
+void menu_set_count(AbsMenu *m, int i);
+
+/* Obtains menu item count */
+int menu_get_count(AbsMenu *m);
+
+/* Sets the selected item of the menu. Applies scrolling
+ * corrections to make sure item is visible */
+void menu_select_item(AbsMenu *m, int i);
+
+/* Paints menu to screen. Does not call refresh() */
+void menu_paint(AbsMenu *m);
+
+/* Performs appropriate action in response to key ch. For example,
+ * if ch is KEY_UP, decrement m->sel_item, etc. */
+void menu_handle_key(AbsMenu *m, int ch);
+
+#endif
+
diff --git a/aecat.c b/aecat.c
new file mode 100644
index 0000000..ac7235c
--- /dev/null
+++ b/aecat.c
@@ -0,0 +1,275 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "document.h"
+#include "vlayer.h"
+#include "export.h"
+#include <stdbool.h>
+
+#include "bores/bores.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+bool clear_screen = false;
+bool suppress_newlines = false;
+ /* whether to suppress newlines on output. */
+bool use_color = true;
+char *outputfile;
+
+FILE *f;
+
+Document *doc; /* the document we are outputting */
+int layer_number; /* the layer we will output; -1 means composite */
+Layer *lyr; /* the layer we are printing; NULL if printing composite */
+int width, height;
+
+struct html_output_state_t {
+ bool font_tag_open, blink_tag_open; /* which html tags are open */
+ int color; /* The color we are currently outputting text in.
+ * This is a full 0-15 color code.*/
+ int bgcolor; /* The color we are currently putting text onto.
+ * This is a full 0-15 color code.*/
+};
+
+/* Extracts a cell from the appropriate layer (or build one,
+ * if we are dealing with a composite). Returns it. */
+void get_decoded_cell(int x, int y, DecodedCell *dec) {
+ if (lyr) decode_cell(&lyr->cells[x][y], dec);
+ else {
+ Cell c = document_calc_effective_cell(doc, x, y);
+ decode_cell(&c, dec);
+ }
+}
+
+void output_text(void) {
+ VirtualLayer *vl;
+
+ if (lyr) vl = vlayer_create_from_layer(lyr);
+ else vl = vlayer_create_from_composite(doc);
+
+ if (!vl) {
+ fprintf(stderr, "Error creating virtual layer. Is the document empty?\n");
+ exit(2);
+ }
+
+ if (clear_screen) fputs("\x1B[2J\x1B[H", f);
+ if (!export_vlayer_to_ansi(vl, use_color, !suppress_newlines, false, f)) {
+ fprintf(stderr, "Error exporting virtual layer to ansi.\n");
+ exit(2);
+ }
+
+ vlayer_destroy(vl);
+}
+
+#define COL_BLACK 0
+#define COL_RED 1
+#define COL_GREEN 2
+#define COL_YELLOW 3
+#define COL_BLUE 4
+#define COL_MAGENTA 5
+#define COL_CYAN 6
+#define COL_WHITE 7
+
+static char *hex_codes[16] = {
+ "000000", "990000", "009900", "999900",
+ "000099", "990099", "009999", "999999",
+ "404040", "ff0000", "00ff00", "ffff00",
+ "0000ff", "ff00ff", "00ffff", "ffffff" };
+
+void output_html(void) {
+ int x, y;
+ struct html_output_state_t cur_state;
+ DecodedCell dec;
+
+ fputs("<html><body style=\"color:#ffffff;background-color:#000000;\">"
+ "<pre>", f);
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ get_decoded_cell(x, y, &dec);
+
+ /* first set up the blink tag */
+ if (use_color && dec.blink != cur_state.blink_tag_open) {
+ fprintf(f, "<%sblink>", dec.blink ? "" : "/");
+ cur_state.blink_tag_open = dec.blink;
+ }
+
+ /* set up color */
+ if (use_color && (dec.fg != cur_state.color ||
+ dec.bg != cur_state.bgcolor)) {
+ if (cur_state.font_tag_open) fputs("</span>", f);
+ fprintf(f, "<span style=\"color:#%s;background-color:#%s;\">",
+ hex_codes[dec.fg], hex_codes[dec.bg]);
+ cur_state.color = dec.fg;
+ cur_state.bgcolor = dec.bg;
+ cur_state.font_tag_open = true;
+ }
+
+ /* now render the character */
+ if (dec.ch >= 0 && dec.ch <= 32) fputs(" ", f);
+ else if (dec.ch == '&') fputs("&amp;", f);
+ else if (dec.ch == '<') fputs("&lt;", f);
+ else if (dec.ch == '>') fputs("&gt;", f);
+ else fputc(dec.ch, f);
+ }
+ fputs("\n", f);
+ }
+
+ /* close tags as needed and call it a day */
+ if (cur_state.font_tag_open) fputs("</span>", f);
+ if (cur_state.blink_tag_open) fputs("</blink>", f);
+ fputs("</pre></body></html>", f);
+}
+
+void output_comment(void) {
+ printf ("%s\n", doc->metainfo);
+}
+
+void output_layercount(void) {
+ printf ("%d\n", doc->layer_count);
+}
+
+#define MYSYNTAX \
+ "Syntax: aecat [-b] [-c] [-{n|N}] [{-p | -l <layer_num>}]\n" \
+ " [-f <format>] [-o <output_file>] inputfile\n" \
+ "\n" \
+ " -f : specifies output format - can be text, html or comment\n" \
+ " The 'comment' format extracts document metadata.\n" \
+ " -c : prepend a 'clear screen' escape sequence (only valid when\n" \
+ " outputting text)\n" \
+ " -o : writes output to specified file rather than stdout\n" \
+ " -b : disables output of color (only characters will be\n" \
+ " printed).\n" \
+ " -l : specifies which layer of the document is to be used.\n" \
+ " (must be an index, not a layer name). By default,\n" \
+ " layer 0 will be used.\n" \
+ " -L : displays how many layers the document has.\n" \
+ " -p : exports a composite, that is, overlays all visible layers,\n" \
+ " paying attention to layer transparency, etc. The size of the\n" \
+ " composite will be the size of the first layer\n" \
+ " -n : suppress output of newlines\n" \
+ " -h : prints this help text\n"
+
+void rtfm() { /* rtfm = Read the FAQ and Manual, of course :-) */
+ fprintf(stderr, MYSYNTAX);
+ exit(1);
+}
+
+#define FMT_TEXT 1
+#define FMT_HTML 2
+#define FMT_COMMENT 3
+#define FMT_LAYERS 4
+
+int main(int argc, char **argv) {
+ static char optstring[] = "o:chl:Lbpf:n";
+ char *inputfile;
+ int ch;
+
+ int out_fmt = 0; /* In what format to output. */
+
+ while (0 < (ch = getopt(argc, argv, optstring)) ) {
+ switch (ch) {
+ case 'c': clear_screen = true; break;
+ case 'o': outputfile = strdup(optarg); break;
+ case 'l': layer_number = atoi(optarg); break;
+ case 'L': out_fmt = FMT_LAYERS; break;
+ case 'p': layer_number = -1; break;
+ case 'b': use_color = false; break;
+ case 'n': suppress_newlines = true; break;
+ case 'f':
+ if (strcmp(optarg, "text") == 0)
+ out_fmt = FMT_TEXT;
+ else if (strcmp(optarg, "html") == 0)
+ out_fmt = FMT_HTML;
+ else if (strcmp(optarg, "comment") == 0)
+ out_fmt = FMT_COMMENT;
+ else {
+ fprintf(stderr, "Invalid format \"%s\"\n", optarg);
+ exit(1);
+ }
+ break;
+ default : rtfm();
+ }
+ }
+
+ if (!out_fmt)
+ out_fmt = FMT_TEXT;
+
+ if (out_fmt != FMT_TEXT && clear_screen)
+ fprintf(stderr, "Warning: -c option only valid when outputting text\n");
+
+ if (out_fmt != FMT_TEXT && suppress_newlines)
+ fprintf(stderr, "Warning: -n option only valid when "
+ "outputting text\n");
+
+ if (optind >= argc) rtfm();
+ inputfile = strdup(argv[optind]);
+
+ if (! (doc = document_load_from(inputfile)) ) {
+ fprintf(stderr, "Error loading document from %s (bad format?).\n",
+ inputfile);
+ fprintf(stderr, "Error description:\n %s\n", aeff_get_error());
+ exit(1);
+ }
+
+ if (layer_number >= doc->layer_count) {
+ if (layer_number)
+ fprintf(stderr, "Document %s does not have the specified layer: %d\n",
+ inputfile, layer_number);
+ else
+ fprintf(stderr, "Document %s has no layers.\n", inputfile);
+ exit(1);
+ }
+
+ width = doc->layers[0]->width;
+ height = doc->layers[0]->height;
+ lyr = layer_number >= 0 ? doc->layers[layer_number] : NULL;
+
+ if (outputfile && !(f = fopen(outputfile, "w"))) {
+ fprintf(stderr, "Error opening %s for writing.\n", outputfile);
+ exit(1);
+ }
+ else f = stdout; /* print to standard output if no output file specified */
+
+ switch(out_fmt) {
+ case FMT_TEXT: output_text(); break;
+ case FMT_HTML: output_html(); break;
+ case FMT_COMMENT: output_comment(); break;
+ case FMT_LAYERS: output_layercount(); break;
+ }
+
+ if (f != stdout) fclose(f);
+ return 0;
+}
diff --git a/aeff.c b/aeff.c
new file mode 100644
index 0000000..e6058f5
--- /dev/null
+++ b/aeff.c
@@ -0,0 +1,349 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+/*
+AEWAN FILE FORMAT:
+
+Any line can contain as many initial spaces as it wants, but
+TRAILING SPACES may be significant in string values and other places.
+
+A header whose name is BLAH is written as a line containing exactly:
+
+ <BLAH
+
+A footer whose name is BLAH is written as a line containing exactly:
+
+ >BLAH
+
+A labeled integer (label blah, value 42) will be a line of the form:
+
+ blah: int: 42
+
+A labeled string (label blah, value "Line 1\nLine 2\nLine 3") will be:
+
+ blah: string: Line 1\:Line 2\:Line 3
+
+Notice that newlines are escaped as '\:'. The rule is that any character
+in the range 1 to 31, inclusive, is escaped as '\' followed by ('0' + ch).
+A backslash is encoded as '\\'
+
+Notice that all data lines have three fields, delimited by ": " (the
+space is significant and is necessary).
+*/
+
+#include "aeff.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <zlib.h>
+#include "bores/bores.h"
+
+char *err_string = 0; /* error buffer */
+
+struct AeFile_ {
+ gzFile f;
+ int indent_level; /* current indent level, for pretty formatting.
+ * Purely cosmetic. */
+};
+
+static bool read_parse_data_line(gzFile f, char **label, char **type,
+ char **value) {
+ /* reads and splits a data line, also converting the escape sequences
+ * found in the third field. If parse fails, set err_string and
+ * returns false. On success, returns true. */
+ char *field_start[3];
+ char *line;
+
+ autod_begin;
+ autod_register(line, free);
+
+ autod_assign( line, freadline_ex(f, gzgetc) );
+
+ /* look for ':' field separators and note their locations */
+ field_start[0] = line;
+ if ( ! (field_start[1] = strchr(line, ':')) ||
+ ! (field_start[2] = strchr(field_start[1] + 1, ':')) ) {
+
+ dstrset(&err_string, "There's a data line with <3 fields.");
+ autod_return_value(false);
+ }
+
+ /* split string by putting 0's on the field limit locations,
+ * and advacing the limits by 2 positions (to skip over the
+ * 0 we just put in and the space that immediately succeeds it) */
+ *(field_start[1]) = 0; field_start[1] += 2;
+ *(field_start[2]) = 0; field_start[2] += 2;
+
+ /* discard leading spaces from label that originated from the
+ * indentation */
+ while (*(field_start[0]) == ' ' ||
+ *(field_start[0]) == '\t') field_start[0]++;
+
+ /* if we ended up with an empty field, we have bad syntax */
+ if (field_start[0] >= field_start[1]) {
+ dstrset(&err_string, "There's a data line with an empty label");
+ autod_return_value(false);
+ }
+
+ /* now copy the needed portions to the return variables */
+ if (label) *label = sstrdup(field_start[0]);
+ if (type) *type = sstrdup(field_start[1]);
+ if (value) *value = sstrdup(field_start[2]);
+
+ /* and decode escape sequences found in value */
+ if (value) {
+ const char *r = *value;
+ char *w = *value;
+
+ while (*r) {
+ if (*r == '\\')
+ r++, *w = (*r == '\\') ? '\\' : *r - '0';
+ else
+ *w = *r;
+
+ r++, w++;
+ }
+
+ *w = 0;
+ }
+
+ /* and call it a day */
+ autod_return_value(true);
+}
+
+static void aeff_indent(AeFile *f) {
+ int n = f->indent_level;
+ while (n-- > 0) gzputc(f->f, '\t');
+}
+
+AeFile* aeff_open(const char *filename, char mode) {
+ AeFile *f = zalloc(sizeof(AeFile));
+
+ f->f = gzopen(filename, mode == 'r' ? "rb" : "wb");
+ if (!f->f) {
+ free(f);
+ zfree(&err_string);
+ err_string = dsprintf("%s: %s", filename, strerror(errno));
+ return NULL;
+ }
+
+ f->indent_level = 0;
+
+ return f;
+}
+
+const char *aeff_get_error(void) {
+ return err_string;
+}
+
+void aeff_set_error(const char *s) {
+ zfree(&err_string);
+ err_string = sstrdup(s);
+}
+
+void aeff_close(AeFile* f) {
+ gzclose(f->f);
+ sfree(f);
+}
+
+void aeff_write_header(AeFile *f, const char *header_name) {
+ aeff_indent(f);
+ gzprintf(f->f, "<%s\n", header_name);
+ f->indent_level++;
+}
+
+/* generalization for read_header and read_footer */
+static bool aeff_read_mark(AeFile *f, const char *mark_name, char pref) {
+ char *line;
+ char *s;
+ zfree(&err_string);
+
+ autod_begin;
+ autod_register(line, free);
+
+ autod_assign(line, freadline_ex(f->f, gzgetc));
+
+ /* if EOF was reached before anything could be read, something is wrong */
+ if (!line) {
+ err_string = dsprintf("EOF reading mark '%c%s'", pref, mark_name);
+ autod_return_value(false);
+ }
+
+ /* discard leading blanks, store start of real text in s */
+ s = line;
+ while (*s == ' ' || *s == '\t') s++;
+
+ /* try to recognize the line as a header/footer, and match its name */
+ if (strcmp(&s[1], mark_name) || s[0] != pref) {
+ err_string = dsprintf("Mark '%c%s' not found.", pref, mark_name);
+ autod_return_value(false);
+ }
+
+ /* everything checks ok */
+ autod_return_value(true);
+}
+
+bool aeff_read_header(AeFile *f, const char *header_name) {
+ return aeff_read_mark(f, header_name, '<');
+}
+
+void aeff_write_footer(AeFile *f, const char *footer_name) {
+ f->indent_level--;
+ aeff_indent(f);
+ gzprintf(f->f, ">%s\n", footer_name);
+}
+
+bool aeff_read_footer(AeFile *f, const char *footer_name) {
+ return aeff_read_mark(f, footer_name, '>');
+}
+
+void aeff_write_int(AeFile *f, const char *label, int a) {
+ aeff_indent(f);
+ gzprintf(f->f, "%s: int: %d\n", label, a);
+}
+
+bool aeff_read_int(AeFile *f, const char *label, int *ret) {
+ char *rlabel, *rtype, *rvalue;
+
+ autod_begin;
+ autod_register(rlabel, free);
+ autod_register(rtype, free);
+ autod_register(rvalue, free);
+
+ if (!read_parse_data_line(f->f, &rlabel, &rtype, &rvalue))
+ return false;
+
+ if (strcmp(rtype, "int")) {
+ zfree(&err_string);
+ err_string = dsprintf("Field '%s' not marked as integer", label);
+
+ autod_return_value(false);
+ }
+
+ if (strcmp(rlabel, label)) {
+ zfree(&err_string);
+ err_string = dsprintf("Expected label '%s', found '%s'", label, rlabel);
+
+ autod_return_value(false);
+ }
+
+ if (ret) *ret = atoi(rvalue);
+
+ autod_return_value(true);
+}
+
+void aeff_write_bool(AeFile *f, const char *label, bool a) {
+ aeff_indent(f);
+ gzprintf(f->f, "%s: bool: %s\n", label, a ? "true" : "false");
+}
+
+bool aeff_read_bool(AeFile *f, const char *label, bool *ret) {
+ char *rlabel, *rtype, *rvalue;
+
+ autod_begin;
+ autod_register(rlabel, free);
+ autod_register(rtype, free);
+ autod_register(rvalue, free);
+
+ if (!read_parse_data_line(f->f, &rlabel, &rtype, &rvalue))
+ return false;
+
+ if (strcmp(rtype, "bool")) {
+ zfree(&err_string);
+ err_string = dsprintf("Field '%s' not marked as bool", label);
+
+ autod_return_value(false);
+ }
+
+ if (strcmp(rlabel, label)) {
+ zfree(&err_string);
+ err_string = dsprintf("Expected label '%s', found '%s'", label, rlabel);
+
+ autod_return_value(false);
+ }
+
+ if (ret) *ret = (*rvalue == 't') ? true : false;
+
+ autod_return_value(true);
+}
+
+void aeff_write_string(AeFile *f, const char *label, const char *s) {
+ aeff_indent(f);
+ gzprintf(f->f, "%s: str: ", label);
+
+ /* now encode and write string */
+ while (*s) {
+ if (*s >= 0 && *s <= 31) {
+ gzputc(f->f, '\\');
+ gzputc(f->f, *s + '0');
+ }
+ else if (*s == '\\') gzputs(f->f, "\\\\");
+ else gzputc(f->f, *s);
+ s++;
+ }
+
+ gzputc(f->f, '\n');
+}
+
+bool aeff_read_string(AeFile *f, const char *label, char **ret) {
+ char *rlabel, *rtype, *rvalue;
+
+ autod_begin;
+ autod_register(rlabel, free);
+ autod_register(rtype, free);
+ autod_register(rvalue, free);
+
+ if (!read_parse_data_line(f->f, &rlabel, &rtype, &rvalue))
+ autod_return_value(false);
+
+ if (strcmp(rtype, "str")) {
+ zfree(&err_string);
+ err_string = dsprintf("Field '%s' not marked as string", label);
+
+ autod_return_value(false);
+ }
+
+ if (strcmp(rlabel, label)) {
+ zfree(&err_string);
+ err_string = dsprintf("Expected label '%s', found '%s'", label, rlabel);
+
+ autod_return_value(false);
+ }
+
+ if (ret) *ret = sstrdup(rvalue);
+
+ autod_return_value(true);
+}
+
+
diff --git a/aeff.h b/aeff.h
new file mode 100644
index 0000000..dc0c285
--- /dev/null
+++ b/aeff.h
@@ -0,0 +1,104 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+/* This module handles reading and writing aewan-formatted files.
+ * These functions provide an abstration layer for actual I/O,
+ * nothing else. The document_save, layer_save, and other functions
+ * call the functions herein.
+ *
+ * When any functions herein find an error, they set an internal
+ * static error description variable in addition to returning an error
+ * code. You can query the error description through a call to
+ * aeff_get_error()
+ *
+ * All aeff_read_* functions return bool indicating success or failure,
+ * and set the internal error string on the latter case. They also take
+ * label parameters, which they use to check whether the next piece
+ * of data in the stream has that label (returning an error if it doesn't).
+ */
+
+#ifndef _btco_aewan_aeff_h
+#define _btco_aewan_aeff_h
+
+#include <stdbool.h>
+#include "bores/bores.h"
+
+typedef struct AeFile_ AeFile; /* opaque file type */
+
+/* Open a file for I/O. <filename> is the name of the file to open,
+ * <mode> is either 'r' or 'w' and you can probably guess what it means.
+ * Returns the file handle or NULL on error (in which case the internal
+ * error string is set appropriately) */
+AeFile* aeff_open(const char *filename, char mode);
+
+/* Queries for a description of the last error. CAUTION: this function
+ * returns a pointer to an internal buffer that may be deallocated
+ * or overwritten at whim. So don't keep the returned pointer, just
+ * use it and forget about it, ask for it again later if you need it.
+ *
+ * This function returns NULL if no error string is set. */
+const char *aeff_get_error(void);
+
+/* Set an artificial error. */
+void aeff_set_error(const char *e);
+
+/* Closes a file opened with aeff_open */
+void aeff_close(AeFile* f);
+
+/* Reads/Writes a header (headers contain no data, they are just
+ * used for consistency checking) */
+void aeff_write_header(AeFile *f, const char *header_name);
+bool aeff_read_header(AeFile *f, const char *header_name);
+
+/* Reads/Writes a footer (footers contain no data, they are just
+ * used for consistency checking) */
+void aeff_write_footer(AeFile *f, const char *footer_name);
+bool aeff_read_footer(AeFile *f, const char *footer_name);
+
+/* Reads/writes a labeled integer */
+void aeff_write_int(AeFile *f, const char *label, int a);
+bool aeff_read_int(AeFile *f, const char *label, int *ret);
+
+/* Reads/writes a labeled boolean */
+void aeff_write_bool(AeFile *f, const char *label, bool a);
+bool aeff_read_bool(AeFile *f, const char *label, bool *ret);
+
+/* Reads/writes a labeled string.
+ * On the read function, the returned pointer points to a DYNAMICALLY
+ * ALLOCATED block that the caller is responsible for freeing. */
+void aeff_write_string(AeFile *f, const char *label, const char *s);
+bool aeff_read_string(AeFile *f, const char *label, char **s);
+
+#endif
+
+
diff --git a/aemakeflic.c b/aemakeflic.c
new file mode 100644
index 0000000..e162a03
--- /dev/null
+++ b/aemakeflic.c
@@ -0,0 +1,249 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "document.h"
+#include "vlayer.h"
+#include "export.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#define AEFLIC_RTFM \
+"Syntax: aemakeflic [options] input.ae [outputfile.ext]\n" \
+"\n" \
+" Produces an animation file from an aewan document. Each layer in the\n" \
+" document will be used as one frame of the animation. See the man page\n" \
+" for more information.\n" \
+"\n" \
+" Options:\n" \
+"\n" \
+" -f {less|sh} movie format ('less movie' or shell-script)\n" \
+" The default is less.\n" \
+" -N suppress initial screen with instructions for\n" \
+" the given format\n" \
+" -b Disable colors (use text only)\n" \
+" -d {delay} Delay in milliseconds between frames\n" \
+"\n" \
+
+#define DEFAULT_DELAY 100
+
+/* settings */
+FILE *outf; /* the output file */
+bool add_instructions = true;
+Document *doc; /* the document we are converting */
+int width, height; /* animation dimensions */
+bool use_color = true;
+int interframe_delay = DEFAULT_DELAY;
+ /* delay between frames (shellscript only)
+ * given in milliseconds */
+
+void rtfm() {
+ fputs(AEFLIC_RTFM,stderr);
+ exit(1);
+}
+
+void output_lessmovie_instructions() {
+ const int instruction_lines = 18; /* VERY IMPORTANT: keep this value
+ * in sync with the message below.
+ * It indicates how many lines it
+ * occupies! */
+ const int instruction_cols = 70; /* this can be overestimated but
+ * not underestimated */
+ int lines_left;
+ int i;
+
+ fprintf(outf,
+ "----------------------------------------[ TOP ]----------\n"
+ "AEWAN LESS-MOVIE\n\n"
+ "This is an ascii animation intended to be viewed in the 'less'\n"
+ "pager. You must set your terminal dimensions to the following:\n\n"
+ " %d columns x %d rows\n\n"
+ "Then run 'less -c -r <filename>.ae' and hold down the PageDown key\n"
+ "to see the animation play.\n\n"
+ "You can tell if the terminal dimensions are correct by looking at\n"
+ "the top and bottom dotted lines: the one marked '[ TOP ]' should\n"
+ "appear at the topmost line of the terminal and the dotted line\n"
+ "marked [ BOTTOM ] should appear at the bottommost. As you page-down\n"
+ "a few times, they should REMAIN FIXED, not move around.\n\n"
+ "This animation was generated with AEWAN, an open-source ascii and\n"
+ "animation editor. Visit http://aewan.sourceforge.net for more info.\n"
+ , width, height+1);
+
+ lines_left = height - instruction_lines - 1;
+ if (lines_left < 1 || width < instruction_cols) {
+ fprintf(stderr, "Error: can't add instructions because the document\n"
+ "dimensions are too small. Height must be at least\n"
+ "%d and width must be at least %d.\n",
+ instruction_lines, instruction_cols);
+ exit(2);
+ }
+
+ while (lines_left > 1) {
+ fputs("\n", outf);
+ lines_left--;
+ }
+
+ fputs("----------------------------------------[ BOTTOM ]-------\n",outf);
+
+ for (i = 4; i >= 1; i--) {
+ fputs("----------------------------------------[ TOP ]----------\n",outf);
+ lines_left = height - 2;
+
+ fprintf(outf, "(movie starts in %d frame[s])...\n", i);
+ lines_left--;
+
+ while (lines_left-- > 0) fputs("\n", outf);
+ fputs("----------------------------------------[ BOTTOM ]-------\n",outf);
+ }
+}
+
+void output_shellscript_instructions() {
+ fprintf(outf,
+"echo 'AEWAN SHELLSCRIPT ANIMATION'\n"
+"echo 'This is an aewan animation shellscript. It will now play an'\n"
+"echo 'animation on your terminal. Please make sure the terminal'\n"
+"echo 'has at least the following dimensions:'\n"
+"echo ' %d lines, %d columns'\n"
+"echo\n"
+"echo 'This animation was generated with AEWAN, an open-source ascii art and'\n"
+"echo 'and animation editor. For more info, see http://aewan.sourceforge.net'\n"
+"echo\n"
+"echo 'Press ENTER to start the animation'\n"
+"read\n"
+"echo -ne '\\e[2J\\e[H'\n"
+ , height, width);
+}
+
+void output_lessmovie() {
+ int i;
+
+ if (add_instructions) output_lessmovie_instructions();
+
+ for (i = 0; i < doc->layer_count; i++) {
+ VirtualLayer *vl = vlayer_create_from_layer(doc->layers[i]);
+ export_vlayer_to_ansi(vl, use_color, true, false, outf);
+ vlayer_destroy(vl);
+ }
+}
+
+void output_shellscript() {
+ int i;
+
+ fputs("#!/bin/bash\n"
+ "# This is an aewan animation shellscript. Upon execution,\n"
+ "# it will play an animation on the terminal.\n"
+ "# Aewan is an open-source ascii art and animation editor.\n"
+ "# http://aewan.sourceforge.net\n"
+ "\n"
+ "echo -ne '\\e[2J\\e[H'\n", outf);
+
+ if (add_instructions) output_shellscript_instructions();
+
+ for (i = 0; i < doc->layer_count; i++) {
+ VirtualLayer *vl = vlayer_create_from_layer(doc->layers[i]);
+ fputs("echo -ne '\\e[H'\n", outf);
+ fputs("cat <<QWPOEIURASDKJFAS\n", outf);
+ export_vlayer_to_ansi(vl, use_color, true, true, outf);
+ fputs("\nQWPOEIURASDKJFAS\n", outf);
+ /* FIXME: heinous bug: if the layer drawing mentions
+ * the word QWPOEIURASDKJFAS at the beginning of a line,
+ * bash will get confused. */
+ fprintf(outf, "sleep %.3f\n", interframe_delay / 1000.0f);
+ vlayer_destroy(vl);
+ }
+}
+
+#define FMT_LESS 0
+#define FMT_SH 1
+int main(int argc, char **argv) {
+ const char optstr[] = "f:Nbd";
+ int ch;
+ int format = FMT_LESS;
+ const char *inputfile, *outputfile;
+
+ while (0 <= (ch = getopt(argc, argv, optstr))) {
+ switch (ch) {
+ case 'f':
+ if (!strcasecmp(optarg, "less")) format = FMT_LESS;
+ else if (!strcasecmp(optarg, "sh")) format = FMT_SH;
+ else {
+ fputs("Unrecognized animation format!\n", stderr);
+ return 1;
+ }
+ break;
+ case 'N': add_instructions = false; break;
+ case 'b': use_color = false; break;
+ case 'd': interframe_delay = atoi(optarg); break;
+ default: rtfm();
+ }
+ }
+
+ if (optind >= argc) rtfm();
+ inputfile = argv[optind];
+ outputfile = (optind + 1 >= argc) ? NULL : argv[optind+1];
+
+ if (outputfile) {
+ if (!(outf = fopen(outputfile, "w"))) {
+ perror(outputfile);
+ fputs("Can't write outputfile.\n", stderr);
+ return 2;
+ }
+ }
+ else outf = stdout; /* use stdout for output if no output file specified */
+
+ /* load document */
+ if (!(doc = document_load_from(inputfile))) {
+ fprintf(stderr, "Error loading document from %s.\n", inputfile);
+ fprintf(stderr, "Error description: %s\n", aeff_get_error());
+ return 2;
+ }
+
+ if (0 >= doc->layer_count) {
+ fprintf(stderr, "Document is empty. Can't create animation.\n");
+ return 2;
+ }
+
+ width = doc->layers[0]->width;
+ height = doc->layers[0]->height;
+
+ switch (format) {
+ case FMT_LESS: output_lessmovie(); break;
+ case FMT_SH: output_shellscript(); break;
+ }
+
+ if (outf != stdout) fclose(outf);
+ return 0;
+}
+
diff --git a/aewan.c b/aewan.c
new file mode 100644
index 0000000..2efc3b7
--- /dev/null
+++ b/aewan.c
@@ -0,0 +1,218 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#include "bores/bores.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <ncurses.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "document.h"
+#include "keys.h"
+#include "ui.h"
+#include "psd.h"
+#include "handlekey.h"
+#include "welcomedlg.h"
+#include "keybind.h"
+#include "init_aewl.h"
+
+/* ----------------------------------------------------------------------- */
+/* function declarations */
+/* ----------------------------------------------------------------------- */
+
+/* Redraws status bar at the top of the screen */
+void paint_status_bar(void);
+
+/* Paints the desktop background */
+void paint_desktop(void);
+
+/* Redraws screen: status bar, canvas, etc */
+void paint_screen(void);
+
+/* ----------------------------------------------------------------------- */
+/* function implementations */
+/* ----------------------------------------------------------------------- */
+void paint_status_bar() {
+ kurses_move(0, kurses_height() - 1);
+ kurses_color(3, 0);
+ printw("[Lyr %2d] (%3d, %3d) ", _lyr, _x, _y);
+
+ if (_selmode == SM_NONE) {
+ printw("%-20s", _doc->layer_count ? _doc->layers[_lyr]->name : "[empty]");
+ kurses_color(3, 0);
+ addstr(" ");
+
+ kurses_color(_fg, _bg);
+ addstr("AaBbCc");
+ kurses_color(7, 0);
+ addstr(" ");
+
+ if (_insmode) {
+ kurses_color(0, 6 + 16);
+ printw(" INSERT ");
+ kurses_color(7, 0);
+ }
+ else printw(" ");
+
+ if (_lgmode) {
+ kurses_color(0, 4);
+ addstr(" LINES! ");
+ kurses_color(7, 0);
+ }
+ else printw(" ");
+
+ if (_compmode) {
+ kurses_color(0, 5);
+ addstr(" COMPOS ");
+ kurses_color(7, 0);
+ }
+ }
+ else if (_selmode == SM_SELECT) {
+ kurses_color(0, 2);
+ printw(" SELECT ");
+ kurses_color(2, 0);
+ printw(" (c)opy (m)ove (e)rase (f)g-tint (b)g-tint (o)-edge");
+ }
+ else {
+ kurses_color(0, 1);
+ printw(" FLOAT ");
+ kurses_color(1, 0);
+ printw(" (s)tamp (x) flip-x (y) flip-y (t)ransparent ");
+ }
+}
+
+void layer_paint_callback(int x, int y, int *ch, int *attr) {
+ int x0, x1, y0, y1;
+ get_norm_sel(&x0, &y0, &x1, &y1);
+
+ if (x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ /* invert the colors (approximatelly) */
+ *attr = ((*attr & 0x0F) << 4) | (*attr >> 4);
+ *attr &= 0xF7; /* turn of blinking attribute */
+ }
+}
+
+void paint_screen() {
+ int scr_width, scr_height, i;
+
+ scr_width = kurses_width();
+ scr_height = kurses_height();
+
+ erase();
+ paint_desktop();
+ paint_status_bar();
+ if (doc_empty()) {
+ static char *msg = "[Document contains no layers; press F1 for menu]";
+ kurses_move((scr_width - strlen(msg)) / 2, scr_height / 2);
+ kurses_color(7, 0);
+ printw(msg);
+ refresh();
+ return;
+ }
+
+ /* if in composite mode, paint all visible layers in reverse order */
+ if (_compmode) {
+ for (i = _doc->layer_count - 1; i >= 0; i--) {
+ Layer *l = _doc->layers[i];
+ if (l->visible)
+ layer_paint(l, -_svx, -_svy, 0, 0,
+ scr_width, scr_height - 1,
+ (_selmode == SM_SELECT && i == _lyr) ?
+ layer_paint_callback : 0);
+ }
+ }
+ else {
+ /* paint only current layer regardless of visibility, and with no
+ * transparency */
+ layer_paint_opaque(_doc->layers[_lyr], -_svx, -_svy, 0, 0,
+ scr_width, scr_height - 1,
+ _selmode == SM_SELECT ? layer_paint_callback : 0);
+ }
+
+ if (_clipboard && _selmode == SM_FLOAT)
+ /* paint clipboard */
+ layer_paint(_clipboard, _x - _svx, _y - _svy, 0, 0,
+ scr_width, scr_height - 1, NULL);
+
+ if (!kurses_move(_x - _svx, _y - _svy)) kurses_move(0, 0);
+ refresh();
+}
+
+void paint_desktop() {
+ int scr_width, scr_height;
+ int x, y;
+
+ scr_width = kurses_width();
+ scr_height = kurses_height();
+
+ kurses_color(8, 0);
+ for (y = 0; y < scr_height - 1; y++) {
+ kurses_move(0, y);
+ for (x = 0; x < scr_width; x++) addch(ACS_CKBOARD);
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+/* main function */
+/* ----------------------------------------------------------------------- */
+int main(int argc, char **argv) {
+ /* debug output to /tmp/aewan.log, or /dev/null */
+ close(2);
+ #ifdef DEBUG
+ if (2 != open("aewan.log", O_WRONLY | O_CREAT | O_TRUNC)) exit(13);
+ #else
+ if (2 != open("/dev/null", O_WRONLY)) exit(13);
+ #endif
+
+ zero_state();
+ kurses_init();
+ atexit(kurses_finalize);
+ keys_init();
+ keybind_init();
+ init_aewl();
+
+ if (argc >= 2)
+ u_load_file(argv[1]);
+ else
+ show_welcome_dlg();
+
+ while (1) {
+ paint_screen();
+ handle_key(getch());
+ }
+}
+
diff --git a/aewl/aewl.c b/aewl/aewl.c
new file mode 100644
index 0000000..0c32fd0
--- /dev/null
+++ b/aewl/aewl.c
@@ -0,0 +1,44 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "aewl.h"
+
+AewlAttrSettings aewl_attrs; /* declared as extern in aewl.h */
+
+void aewl_init(const AewlAttrSettings *s) {
+ /* this is a very complicated function indeed. Lots of things to
+ * initialize: */
+ aewl_attrs = *s;
+}
+
+
diff --git a/aewl/aewl.h b/aewl/aewl.h
new file mode 100644
index 0000000..dceb597
--- /dev/null
+++ b/aewl/aewl.h
@@ -0,0 +1,69 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewl_h
+#define _btco_aewl_h
+
+#include <ncurses.h>
+#include <stdbool.h>
+#include "widget.h"
+
+typedef struct AewlAttrQuad {
+ int normal, focus, highlight, highlight_focus;
+} AewlAttrQuad;
+
+/* defines what curses attributes to use for various interface components */
+typedef struct AewlAttrSettings_ {
+ AewlAttrQuad text;
+ AewlAttrQuad button;
+ AewlAttrQuad frame;
+ AewlAttrQuad field;
+ int field_pad; /* color of the character with which text fields
+ * are padded */
+} AewlAttrSettings;
+
+#define AEWL_ATTR(type, focused, highlighted) ( focused ? \
+ ( highlighted ? aewl_attrs.type.highlight_focus : aewl_attrs.type.focus ) \
+ : \
+ ( highlighted ? aewl_attrs.type.highlight : aewl_attrs.type.normal) )
+
+
+extern AewlAttrSettings aewl_attrs;
+
+/* Initializes the widget library. You must fill an AewlAttrSettings structure
+ * and pass it to this function to define which attributes will be used
+ * for each interface component */
+void aewl_init(const AewlAttrSettings *s);
+
+#endif
+
diff --git a/aewl/allwidgets.h b/aewl/allwidgets.h
new file mode 100644
index 0000000..7a628ca
--- /dev/null
+++ b/aewl/allwidgets.h
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+/* includes all widget headers */
+
+#include "widget.h"
+#include "button.h"
+#include "field.h"
+#include "form.h"
+#include "label.h"
+#include "listbox.h"
+
diff --git a/aewl/button.c b/aewl/button.c
new file mode 100644
index 0000000..3112a1c
--- /dev/null
+++ b/aewl/button.c
@@ -0,0 +1,96 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "aewl.h"
+#include "button.h"
+#include "util.h"
+#include <string.h>
+#include <stdlib.h>
+
+AewlWidget *aewl_button_create(int x, int y, int width, int shortcut,
+ int result, const char *caption) {
+ AewlButton *b = malloc(sizeof(AewlButton));
+ if (!b) return NULL;
+ memset(b, 0, sizeof(AewlButton));
+
+ if (width <= 0) width = aewl_util_strlen_esc(caption) + 2;
+
+ aewl_widget_fill_defaults(&(b->base));
+ b->base.x = x;
+ b->base.y = y;
+ b->base.height = 1;
+ b->base.width = width;
+ b->base.focusable = true;
+ b->base.shortcut = shortcut;
+
+ b->base.fn_repaint = aewl_button_repaint;
+ b->base.fn_destroy = aewl_button_destroy;
+ b->base.fn_handlekey = aewl_button_handlekey;
+
+ b->caption = strdup(caption);
+ b->result = result;
+
+ return (AewlWidget*) b;
+}
+
+void aewl_button_destroy(AewlWidget *button) {
+ AewlButton *b = (AewlButton*) button;
+ if (b->caption) free(b->caption);
+ free(b);
+}
+
+void aewl_button_repaint(AewlWidget *button, bool focused) {
+ AewlButton *b = (AewlButton*) button;
+ int i;
+ int cx;
+
+ wattrset(b->base.win, AEWL_ATTR(button, focused, false));
+
+ /* print button background by just placing spaces */
+ wmove(b->base.win, b->base.y, b->base.x);
+ for (i = 0; i < b->base.width; i++) waddch(b->base.win, ' ');
+
+ /* center caption and print it */
+ cx = (2 * b->base.x + b->base.width - strlen(b->caption)) / 2;
+ aewl_util_mvwaddstr(b->base.win, b->base.y, cx,
+ AEWL_ATTR(button, focused, false),
+ AEWL_ATTR(button, focused, true),
+ b->caption);
+}
+
+int aewl_button_handlekey(AewlWidget *button, int ch) {
+ AewlButton *b = (AewlButton*) button;
+ return (ch == 10 || ch == ' ') ? b->result : 0;
+}
+
+
diff --git a/aewl/button.h b/aewl/button.h
new file mode 100644
index 0000000..07b4944
--- /dev/null
+++ b/aewl/button.h
@@ -0,0 +1,65 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewl_button_h
+#define _btco_aewl_button_h
+
+#include "widget.h"
+
+/* definition of AewlButton */
+typedef struct AewlButton_ {
+ AewlWidget base; /* the widget */
+ char *caption; /* the text that appears on the button */
+ int result; /* the result code that the button issues
+ * when activated */
+} AewlButton;
+
+/* creates a button with the given parameters. If width is 0, button will
+ * be large enough to contain its caption. shortcut is the shortcut key
+ * to activate the button; result is the result code it yields when
+ * activated. The caption accepts '&' escaping to visually indicate the
+ * shortcut key. */
+AewlWidget *aewl_button_create(int x, int y, int width, int shortcut,
+ int result, const char *caption);
+
+/* destroys a button */
+void aewl_button_destroy(AewlWidget *button);
+
+/* repaint a button */
+void aewl_button_repaint(AewlWidget *button, bool focused);
+
+/* key handler function for buttons */
+int aewl_button_handlekey(AewlWidget *button, int ch);
+
+#endif
+
diff --git a/aewl/field.c b/aewl/field.c
new file mode 100644
index 0000000..189e8e0
--- /dev/null
+++ b/aewl/field.c
@@ -0,0 +1,180 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "aewl.h"
+#include "field.h"
+#include "util.h"
+#include <string.h>
+#include <stdlib.h>
+
+/* field buffer dynamic reallocation settings */
+#define FIELD_DEFAULT_CAP 20
+#define FIELD_CAP_ADD 20
+
+static void aewl_field_ensure_cap(AewlField *f, int cap);
+static void buf_insert_char(char *buf, int cap, int pos, int ch);
+static void buf_del_char(char *buf, int cap, int pos, int ch);
+
+AewlWidget *aewl_field_create(int x, int y, int width, int shortcut,
+ int result, const char *text) {
+ AewlField *f = malloc(sizeof(AewlField));
+ AewlWidget *base;
+
+ if (!f) return NULL;
+
+ memset(f, 0, sizeof(AewlField));
+ base = &f->base;
+
+ aewl_widget_fill_defaults(base);
+ base->x = x;
+ base->y = y;
+ base->width = width;
+ base->height = 1;
+ base->focusable = true;
+ base->shortcut = shortcut;
+ base->fn_repaint = aewl_field_repaint;
+ base->fn_destroy = aewl_field_destroy;
+ base->fn_handlekey = aewl_field_handlekey;
+
+ f->result = result;
+ f->pos = 0;
+ f->buffer = malloc(f->cap = FIELD_DEFAULT_CAP);
+ if (!f->buffer) return NULL;
+
+ if (text) aewl_field_set_text(f, text);
+
+ return (AewlWidget*) f;
+}
+
+void aewl_field_set_text(AewlField *f, const char *text) {
+ int len = strlen(text);
+ aewl_field_ensure_cap(f, len + 1);
+ strcpy(f->buffer, text);
+
+ if (f->pos > len) f->pos = len;
+}
+
+const char *aewl_field_get_text(AewlField *f) {
+ return f->buffer;
+}
+
+void aewl_field_destroy(AewlWidget *w) {
+ AewlField *f = (AewlField*) w;
+ if (f->buffer) free(f->buffer);
+ free(f);
+}
+
+void aewl_field_repaint(AewlWidget *w, bool focused) {
+ int i;
+ AewlField *f = (AewlField*) w;
+ const char *str = f->buffer;
+
+ wattrset(w->win, AEWL_ATTR(field, focused, false));
+
+ /* print text and pad rest of field with spaces */
+ wmove(w->win, w->y, w->x);
+ for (i = 0; i < w->width; i++) {
+ if (*str) {
+ waddch(w->win, *str);
+ str++;
+ }
+ else {
+ wattrset(w->win, aewl_attrs.field_pad);
+ waddch(w->win, '_');
+ }
+
+ }
+
+ /* position cursor where it should be */
+ wmove(w->win, w->y, w->x + f->pos);
+}
+
+int aewl_field_handlekey(AewlWidget *w, int ch) {
+ AewlField *f = (AewlField*) w;
+ int len = strlen(f->buffer);
+
+ /* if it is a 'printable' character, insert it into the field */
+ if (ch >= 32 && ch <= 255 && ch != 127) {
+ aewl_field_ensure_cap(f, len + 2);
+ buf_insert_char(f->buffer, f->cap, f->pos, ch);
+ f->pos++;
+ return 0;
+ }
+
+ /* test for control keys and such */
+ switch (ch) {
+ case 10: return f->result;
+ case KEY_RIGHT: if (f->pos < len) f->pos++; /* it is ok for pos == len */
+ break;
+ case KEY_LEFT: if (f->pos) f->pos--; break;
+ case KEY_HOME: f->pos = 0; break;
+ case KEY_END: f->pos = len; break;
+ case 'U'-'A'+1: aewl_field_set_text(f, ""); break;
+
+ case KEY_BACKSPACE: case 8:
+ if (f->pos) {
+ buf_del_char(f->buffer, f->cap, f->pos - 1, ch);
+ f->pos--;
+ }
+ break;
+
+ case KEY_DC:
+ if (f->pos < len) buf_del_char(f->buffer, f->cap, f->pos, ch);
+ break;
+ }
+
+ return 0;
+}
+
+
+static void aewl_field_ensure_cap(AewlField *f, int cap) {
+ if (f->cap >= cap) return;
+
+ if (! (f->buffer = realloc(f->buffer, f->cap = cap + FIELD_CAP_ADD)) )
+ abort();
+}
+
+static void buf_insert_char(char *buf, int cap, int pos, int ch) {
+ /* this function does NOT reallocate the buffer to make room, it
+ * expects there to be room already */
+ int i;
+ for (i = cap - 1; i > pos; i--) buf[i] = buf[i-1];
+ buf[pos] = ch;
+}
+
+static void buf_del_char(char *buf, int cap, int pos, int ch) {
+ int i;
+ for (i = pos; i < cap - 1; i++) buf[i] = buf[i+1];
+}
+
+
diff --git a/aewl/field.h b/aewl/field.h
new file mode 100644
index 0000000..6de85e4
--- /dev/null
+++ b/aewl/field.h
@@ -0,0 +1,69 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewl_field_h
+#define _btco_aewl_field_h
+
+#include "widget.h"
+
+/* definition of AewlField */
+typedef struct AewlField_ {
+ AewlWidget base; /* the widget */
+ int result; /* result code returned when user presses ENTER
+ * while editing this field */
+ char *buffer; /* text buffer containing this field's text */
+ int cap; /* allocated capacity of above buffer */
+ int pos; /* position of cursor within field */
+} AewlField;
+
+/* creates a field with the given parameters */
+AewlWidget *aewl_field_create(int x, int y, int width, int shortcut,
+ int result, const char *text);
+
+/* destroys a field */
+void aewl_field_destroy(AewlWidget *w);
+
+/* repaint a field */
+void aewl_field_repaint(AewlWidget *w, bool focused);
+
+/* key handler function for fields */
+int aewl_field_handlekey(AewlWidget *w, int ch);
+
+/* sets the field's text to the given text */
+void aewl_field_set_text(AewlField *f, const char *text);
+
+/* returns the field's current text */
+const char *aewl_field_get_text(AewlField *f);
+
+#endif
+
diff --git a/aewl/form.c b/aewl/form.c
new file mode 100644
index 0000000..49112b8
--- /dev/null
+++ b/aewl/form.c
@@ -0,0 +1,133 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "form_int.h"
+
+AewlForm *aewl_form_create(WINDOW *w) {
+ AewlForm *f = malloc(sizeof(struct AewlForm_));
+ if (!f) return NULL;
+
+ f->win = w;
+ f->first_widget = NULL;
+ f->last_widget = NULL;
+ f->focus_widget = NULL;
+ return f;
+}
+
+void aewl_form_add_widget(AewlForm *f, AewlWidget *wid) {
+ wid->win = f->win; /* tell widget where it is supposed to draw itself */
+ wid->form = f; /* tell widget which form it belongs to */
+ wid->next = NULL; /* will be the end of the list */
+
+ if (!f->first_widget) /* form's first widget */
+ f->first_widget = f->last_widget = wid;
+ else /* append to end of list */
+ f->last_widget->next = f->last_widget = wid;
+
+ /* if this widget is focusable, and form does not yet have a focused
+ * widget, this one becomes the focused widget */
+ if (!f->focus_widget && wid->focusable) f->focus_widget = wid;
+}
+
+void aewl_form_paint(AewlForm *f, bool refresh) {
+ AewlWidget *w;
+
+ /* paint all the nonfocused widgets */
+ for (w = f->first_widget; w; w = w->next)
+ if (w != f->focus_widget && w->fn_repaint) w->fn_repaint(w, false);
+
+ /* now paint focus widget */
+ if (f->focus_widget && f->focus_widget->fn_repaint)
+ f->focus_widget->fn_repaint(f->focus_widget, true);
+
+ if (refresh) wrefresh(f->win);
+}
+
+int aewl_form_dispatch_key(AewlForm *f, int ch) {
+ AewlWidget *w;
+ int result;
+
+ if (ch == 9 && f->focus_widget) {
+ /* tab key: move focus to next focusable widget */
+
+ /* notice that if f->focus_widget == NULL, that means that the
+ * form does not have ANY focusable widget, in which case
+ * we don't even enter this 'if' */
+ do {
+ f->focus_widget = f->focus_widget->next;
+ if (!f->focus_widget) f->focus_widget = f->first_widget;
+ } while (!f->focus_widget->focusable);
+
+ aewl_form_paint(f, true);
+ return 0;
+ }
+
+ /* check if the key is a shortcut for some widget; if so, it gets the
+ * focus */
+ for (w = f->first_widget; w; w = w->next) {
+ if (w->shortcut == ch && w->focusable) {
+ f->focus_widget = w;
+ aewl_form_paint(f, true);
+ return 0;
+ }
+ }
+
+ /* deliver key to focused widget, if there is one */
+ if (f->focus_widget && f->focus_widget->fn_handlekey) {
+ result = f->focus_widget->fn_handlekey(f->focus_widget, ch);
+ aewl_form_paint(f, true);
+ return result;
+ }
+
+ return 0; /* nothing done */
+}
+
+void aewl_form_destroy(AewlForm *f) {
+ AewlWidget *tmp, *w = f->first_widget;
+
+ while (w) {
+ tmp = w->next;
+ w->fn_destroy(w);
+ w = tmp;
+ }
+
+ free(f);
+}
+
+AewlWidget *aewl_form_get_focus_widget(AewlForm *fn) {
+ return fn->focus_widget;
+}
+
+
diff --git a/aewl/form.h b/aewl/form.h
new file mode 100644
index 0000000..055d43e
--- /dev/null
+++ b/aewl/form.h
@@ -0,0 +1,97 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewl_form_h
+#define _btco_aewl_form_h
+
+#include <ncurses.h>
+#include <stdbool.h>
+#include "widget.h"
+
+/* Defines a form, an abstract entity used as a container for widgets.
+ * The structure is opaque; see form.c if curious about its internals */
+struct AewlForm_;
+typedef struct AewlForm_ AewlForm;
+
+/* Creates a new form. The passed curses window is where the widgets will
+ * be rendered. Pass stdscr to render the form to the main screen rather
+ * than a window. Returns NULL if a problem occurs (i.e., out of memory) */
+AewlForm *aewl_form_create(WINDOW *w);
+
+/* Adds a widget to a form. The form will be responsible for deleting
+ * it, you needn't (and mustn't) mind */
+void aewl_form_add_widget(AewlForm *frm, AewlWidget *wid);
+
+/* Paints all the form's widgets to the screen (i.e. to the window that
+ * the form is tied with). You only need to call this once, or when
+ * the screen contents are somehow lost. Widgets redraw themselves
+ * when appropriate without your interference.
+ *
+ * This function will call wrefresh on the form's window if refresh == true.
+ */
+void aewl_form_paint(AewlForm *frm, bool refresh);
+
+/* Process a keystroke. This will check what is the widget that currently
+ * has the focus and will deliver the keypress to its handler. Also handles
+ * keys for switching focus and so on. Returns a result code (just a plain
+ * integer -- you can configure your widgets to return certain result codes
+ * when they are activated), or 0 (special result code meaning the key
+ * was not handled by any widget).
+ *
+ * A typical construct for "running" a form is
+ *
+ * aewl_form_paint(f);
+ * while (42 != aewl_form_dispatch_key(ch));
+ * aewl_form_destroy(f);
+ *
+ * The above code will run the form until some widget returns the result
+ * code 42 in response to a keypress.
+ *
+ * We don't provide you a function to do that (such as aewl_form_run or
+ * something) because you will always want to intercept keystrokes and
+ * process them somehow before handing it over to aewl_form_dispatch,
+ * (if nothing else, for knowing when to close the form!) so this 'event
+ * loop' must be written by you.
+ */
+int aewl_form_dispatch_key(AewlForm *frm, int ch);
+
+/* Destroys (deallocates) the given form and ALL WIDGETS WITHIN. Do not
+ * destroy widgets separately! */
+void aewl_form_destroy(AewlForm *frm);
+
+/* Returns which is the focused widget in the form */
+AewlWidget *aewl_form_get_focus_widget(AewlForm *fn);
+
+
+#endif
+
diff --git a/aewl/form_int.h b/aewl/form_int.h
new file mode 100644
index 0000000..52be7a6
--- /dev/null
+++ b/aewl/form_int.h
@@ -0,0 +1,17 @@
+#ifndef aewan_aewl_form_int_h
+#define aewan_aewl_form_int_h
+
+/* Form internals */
+
+#include "form.h"
+struct AewlForm_ {
+ WINDOW *win; /* the curses window that houses this form */
+ AewlWidget *first_widget; /* first widget in form. Others follow in
+ * linked list */
+ AewlWidget *last_widget; /* tail of above linked list */
+ AewlWidget *focus_widget; /* points to the widget that currently has
+ * focus */
+};
+
+#endif
+
diff --git a/aewl/label.c b/aewl/label.c
new file mode 100644
index 0000000..c516f3a
--- /dev/null
+++ b/aewl/label.c
@@ -0,0 +1,104 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "aewl.h"
+#include "label.h"
+#include "util.h"
+#include "form_int.h"
+#include <string.h>
+#include <stdlib.h>
+
+/* creates a label with the given parameters */
+AewlWidget *aewl_label_create(int x, int y, int width, const char *text) {
+ AewlLabel *l = malloc(sizeof(AewlLabel));
+ AewlWidget *base;
+ if (!l) return NULL;
+ memset(l, 0, sizeof(AewlLabel));
+
+ base = &l->base;
+
+ aewl_widget_fill_defaults(base);
+ base->x = x;
+ base->y = y;
+ base->width = (width > 0) ? width : aewl_util_strlen_esc(text);
+ base->height = 1;
+ base->focusable = false;
+ base->shortcut = 0;
+
+ base->fn_repaint = aewl_label_repaint;
+ base->fn_destroy = aewl_label_destroy;
+ base->fn_handlekey = NULL;
+
+ l->caption = strdup(text);
+ if (!l->caption) return NULL;
+
+ return (AewlWidget*) l;
+}
+
+/* destroys a label */
+void aewl_label_destroy(AewlWidget *w) {
+ AewlLabel *l = (AewlLabel*) w;
+ free(l->caption);
+ free(w);
+}
+
+/* repaint a label */
+void aewl_label_repaint(AewlWidget *w, bool focused) {
+ AewlLabel *l = (AewlLabel*) w;
+ int n = w->width;
+
+ if (l->focus_peer && (l->focus_peer == w->form->focus_widget))
+ focused = true;
+
+ /* clear the label first */
+ wmove(w->win, w->y, w->x);
+ while (n--) waddch(w->win, ' ');
+
+ /* now print contents */
+ aewl_util_mvwaddstr(w->win, w->y, w->x,
+ AEWL_ATTR(text, focused, false),
+ AEWL_ATTR(text, focused, true),
+ l->caption);
+}
+
+/* sets the label's text to the given text */
+void aewl_label_set_text(AewlLabel *l, const char *text) {
+ if (l->caption) free(l->caption);
+ l->caption = strdup(text);
+ if (!l->caption) abort();
+}
+
+void aewl_label_set_focus_peer(AewlLabel *l, AewlWidget *peer) {
+ l->focus_peer = peer;
+}
+
diff --git a/aewl/label.h b/aewl/label.h
new file mode 100644
index 0000000..8603b33
--- /dev/null
+++ b/aewl/label.h
@@ -0,0 +1,68 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewl_label_h
+#define _btco_aewl_label_h
+
+#include "widget.h"
+
+/* definition of AewlLabel */
+typedef struct AewlLabel_ {
+ AewlWidget base; /* the widget */
+ char *caption; /* caption to display */
+ AewlWidget *focus_peer; /* the focus peer of the label. The focus peer
+ * is the widget whose focus status determines
+ * whether this label will 'appear' focused or
+ * not. When the peer has the focus, this
+ * widget will be drawn focused */
+} AewlLabel;
+
+/* creates a label with the given parameters. If width is 0,
+ * width is calculated from the width of the text. */
+AewlWidget *aewl_label_create(int x, int y, int width, const char *text);
+
+/* destroys a label */
+void aewl_label_destroy(AewlWidget *w);
+
+/* repaint a label */
+void aewl_label_repaint(AewlWidget *w, bool focused);
+
+/* sets the label's text to the given text */
+void aewl_label_set_text(AewlLabel *l, const char *text);
+
+/* sets the focus peer for this label. See the description above for
+ * what the focus peer is. */
+void aewl_label_set_focus_peer(AewlLabel *l, AewlWidget *peer);
+
+#endif
+
diff --git a/aewl/listbox.c b/aewl/listbox.c
new file mode 100644
index 0000000..e839fee
--- /dev/null
+++ b/aewl/listbox.c
@@ -0,0 +1,200 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "aewl.h"
+#include "listbox.h"
+#include "util.h"
+#include <string.h>
+#include <stdlib.h>
+
+#define DEFAULT_CAPACITY 20
+#define CAPACITY_INCREMENT 20
+
+AewlWidget *aewl_listbox_create(int x, int y, int width, int height,
+ int shortcut, const char *caption, int result) {
+ AewlListBox *lb = malloc(sizeof(AewlListBox));
+ AewlWidget *base = &lb->base;
+ if (!lb) return NULL;
+ memset(lb, 0, sizeof(AewlListBox));
+
+ aewl_widget_fill_defaults(&(lb->base));
+ base->x = x;
+ base->y = y;
+ base->width = width;
+ base->height = height;
+ base->focusable = true;
+ base->shortcut = shortcut;
+
+ base->fn_repaint = aewl_listbox_repaint;
+ base->fn_destroy = aewl_listbox_destroy;
+ base->fn_handlekey = aewl_listbox_handlekey;
+
+ lb->caption = caption ? strdup(caption) : NULL;
+ lb->result = result;
+ lb->sel = 0;
+ lb->iat = 0;
+
+ lb->item_count = 0;
+ lb->capacity = DEFAULT_CAPACITY;
+ lb->items = malloc(sizeof(char*) * DEFAULT_CAPACITY);
+ if (!lb->items) {
+ free(lb);
+ return NULL;
+ }
+
+ return (AewlWidget*) lb;
+}
+
+
+void aewl_listbox_clear(AewlListBox *lb) {
+ int i;
+ for (i = 0; i < lb->item_count; i++)
+ if (lb->items[i]) free(lb->items[i]);
+ lb->item_count = 0;
+ lb->iat = 0;
+ lb->sel = 0;
+}
+
+void aewl_listbox_add(AewlListBox *lb, const char *text) {
+ if (lb->capacity <= lb->item_count) {
+ lb->capacity += CAPACITY_INCREMENT;
+ lb->items = realloc(lb->items, sizeof(char*) * lb->capacity);
+ if (!lb->items) abort();
+ }
+
+ /* add new item to end of list now that we are sure there is
+ * capacity for it */
+ if (! (lb->items[lb->item_count++] = strdup(text)) ) abort();
+}
+
+const char *aewl_listbox_get(AewlListBox *lb, int i) {
+ if (i < 0 || i >= lb->item_count) return NULL;
+ return lb->items[i];
+}
+
+bool aewl_listbox_set(AewlListBox *lb, int i, const char *newvalue) {
+ if (i < 0 || i >= lb->item_count) return false;
+ if (lb->items[i]) free(lb->items[i]);
+ if (! (lb->items[i] = strdup(newvalue)) ) abort();
+ return true;
+}
+
+void aewl_listbox_destroy(AewlWidget *listbox) {
+ AewlListBox *lb = (AewlListBox*) listbox;
+ aewl_listbox_clear(lb);
+ free(lb->items);
+ if (lb->caption) free(lb->caption);
+ free(lb);
+}
+
+void aewl_listbox_repaint(AewlWidget *listbox, bool focused) {
+ AewlListBox *lb = (AewlListBox*) listbox;
+ AewlWidget *base = &lb->base;
+ int i, y;
+
+ /* erase and draw bounding box */
+ wattrset(base->win, AEWL_ATTR(frame, focused, false));
+ aewl_util_erase(base->win, base->x, base->y, base->width, base->height);
+ aewl_util_drawbox(base->win, base->x, base->y, base->width, base->height);
+
+ /* draw caption across top, if any */
+ if (lb->caption)
+ aewl_util_mvwaddstr(base->win, base->y, base->x + 2,
+ AEWL_ATTR(frame, focused, false),
+ AEWL_ATTR(frame, focused, true), lb->caption);
+
+ /* draw items, if there are any */
+ if (lb->item_count) {
+ for ( y = base->y + 1, i = lb->iat;
+ y < base->y + base->height - 1 && i < lb->item_count;
+ i++, y++) {
+
+ wmove(base->win, y, base->x + 1);
+ wattrset(base->win, AEWL_ATTR(field, focused, i == lb->sel));
+ aewl_util_addnstr(base->win, base->width - 2, lb->items[i]);
+ }
+ }
+
+ /* if there are more items than can be seen, show an indication */
+ wattrset(base->win, AEWL_ATTR(frame, focused, true));
+
+ if (lb->iat > 0)
+ mvwaddch(base->win, base->y + 1, base->x + base->width - 1, '^');
+ if (lb->iat + base->height - 2 < lb->item_count)
+ mvwaddch(base->win, base->y + base->height - 2,
+ base->x + base->width - 1, 'v');
+
+ /* move the cursor to the selected item */
+ wmove(base->win, base->y + 1 + (lb->sel - lb->iat), base->x + 1);
+}
+
+int aewl_listbox_handlekey(AewlWidget *listbox, int ch) {
+ AewlListBox *lb = (AewlListBox*) listbox;
+ AewlWidget *base = &lb->base;
+
+ switch (ch) {
+ case KEY_UP: lb->sel--; break;
+ case KEY_DOWN: lb->sel++; break;
+ case KEY_PPAGE: lb->sel -= base->height - 2; break;
+ case KEY_NPAGE: lb->sel += base->height - 2; break;
+ case 10: return lb->result; /* action key */
+ }
+
+ /* apply corrections */
+ if (lb->sel < 0) lb->sel = 0;
+ if (lb->sel >= lb->item_count) lb->sel = lb->item_count - 1;
+
+ /* ensure visibility of selected item */
+ if (lb->sel < lb->iat) lb->iat = lb->sel;
+ if (lb->sel >= lb->iat + (base->height - 2))
+ lb->iat = lb->sel - (base->height - 2) + 1;
+
+ return 0;
+}
+
+int aewl_listbox_get_sel(AewlListBox *lb) {
+ if (lb->sel >= 0 && lb->sel < lb->item_count) return lb->sel;
+ return -1;
+}
+
+static int _compar(const void *p1, const void *p2) {
+ const char **a = (const char**) p1;
+ const char **b = (const char**) p2;
+ return strcmp(*a, *b);
+}
+
+void aewl_listbox_sort(AewlListBox *lb) {
+ qsort(lb->items, lb->item_count, sizeof(const char*), _compar);
+}
+
+
diff --git a/aewl/listbox.h b/aewl/listbox.h
new file mode 100644
index 0000000..a544191
--- /dev/null
+++ b/aewl/listbox.h
@@ -0,0 +1,95 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewl_listbox_h
+#define _btco_aewl_listbox_h
+
+#include "widget.h"
+
+/* definition of AewlListBox */
+typedef struct AewlListBox_ {
+ AewlWidget base; /* the widget */
+ char *caption; /* the title that appears at the top of the listbox's
+ * bounding frame */
+ int result; /* the result code that the listbox issues
+ * when the user presses ENTER on it */
+
+ int sel; /* currently selected item */
+ int iat; /* index at top, that is, what list item is currently being
+ * displayed at the top of the list area. This value changes
+ * as the list is scrolled */
+
+ /* dynamic array of listbox items */
+ int item_count;
+ int capacity;
+ char **items;
+} AewlListBox;
+
+/* creates a list box with the given parameters. The caption accepts
+ * the '&' escape code for highlighting a character. */
+AewlWidget *aewl_listbox_create(int x, int y, int width, int height,
+ int shortcut, const char *caption,
+ int result);
+
+/* empties the list box, that is, deletes all items */
+void aewl_listbox_clear(AewlListBox *lb);
+
+/* adds an item to the list box */
+void aewl_listbox_add(AewlListBox *lb, const char *text);
+
+/* returns the text of the list item whose index is i, or NULL
+ * if the index is invalid. */
+const char *aewl_listbox_get(AewlListBox *lb, int i);
+
+/* returns what index is currently selected in the listbox.
+ * If there is no selection, returns -1. */
+int aewl_listbox_get_sel(AewlListBox *lb);
+
+/* sets the text of the item whose index is i to the given text.
+ * Returns false if (and only if) the index i is invalid. */
+bool aewl_listbox_set(AewlListBox *lb, int i, const char *newvalue);
+
+/* destroys a list box */
+void aewl_listbox_destroy(AewlWidget *listbox);
+
+/* repaint a listbox */
+void aewl_listbox_repaint(AewlWidget *listbox, bool focused);
+
+/* key handler function for listboxes */
+int aewl_listbox_handlekey(AewlWidget *listbox, int ch);
+
+/* sorts the contents of the list box alphabetically */
+void aewl_listbox_sort(AewlListBox *listbox);
+
+#endif
+
diff --git a/aewl/util.c b/aewl/util.c
new file mode 100644
index 0000000..95b3a7c
--- /dev/null
+++ b/aewl/util.c
@@ -0,0 +1,128 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "util.h"
+#define SWAP_VARS(type, x, y) { type tmp; tmp = x; x = y; y = tmp; }
+
+void aewl_util_mvwaddstr(WINDOW *w, int y, int x, int attr1, int attr2,
+ const char *str) {
+ wattrset(w, attr1);
+ wmove(w, y, x);
+
+ while (*str) {
+ if (*str == '&') {
+ str++;
+ wattrset(w, attr2);
+ waddch(w, *str);
+ wattrset(w, attr1);
+ str++;
+ continue;
+ }
+
+ waddch(w, *str);
+ str++;
+ }
+}
+
+int aewl_util_strlen_esc(const char *str) {
+ int l = 0;
+ while (*str) {
+ if (*str == '&') {
+ str+=2;
+ l++;
+ continue;
+ }
+
+ str++;
+ l++;
+ }
+
+ return l;
+}
+
+void aewl_util_drawbox(WINDOW *win, int x0, int y0, int w, int h) {
+ /* left border */
+ aewl_util_drawline_v(win, x0, y0, y0 + h - 1,
+ ACS_ULCORNER, ACS_VLINE, ACS_LLCORNER);
+ /* right border */
+ aewl_util_drawline_v(win, x0 + w - 1, y0, y0 + h - 1,
+ ACS_URCORNER, ACS_VLINE, ACS_LRCORNER);
+ /* top border minus corners */
+ aewl_util_drawline_h(win, x0 + 1, x0 + w - 2, y0,
+ ACS_HLINE, ACS_HLINE, ACS_HLINE);
+ /* bottom border minus corners */
+ aewl_util_drawline_h(win, x0 + 1, x0 + w - 2, y0 + h - 1,
+ ACS_HLINE, ACS_HLINE, ACS_HLINE);
+}
+
+void aewl_util_drawline_h(WINDOW *w, int x0, int x1, int y,
+ int lc, int mc, int rc) {
+ int x;
+ if (x0 > x1) SWAP_VARS(int, x0, x1);
+
+ for (x = x0; x <= x1; x++) {
+ wmove(w, y, x);
+ if (x == x0) waddch(w, lc);
+ else if (x == x1) waddch(w, rc);
+ else waddch(w, mc);
+ }
+}
+
+void aewl_util_drawline_v(WINDOW *w, int x, int y0, int y1,
+ int tc, int mc, int bc) {
+ int y;
+ if (y0 > y1) SWAP_VARS(int, y0, y1);
+
+ for (y = y0; y <= y1; y++) {
+ wmove(w, y, x);
+ if (y == y0) waddch(w, tc);
+ else if (y == y1) waddch(w, bc);
+ else waddch(w, mc);
+ }
+}
+
+void aewl_util_addnstr(WINDOW *w, int n, const char *str) {
+ while (n-- && *str) waddch(w, *(str++));
+}
+
+void aewl_util_erase(WINDOW *win, int x, int y, int w, int h) {
+ int j;
+
+ while (h--) {
+ j = w;
+ wmove(win, y++, x);
+ while (j--) waddch(win, ' ');
+ }
+}
+
+
diff --git a/aewl/util.h b/aewl/util.h
new file mode 100644
index 0000000..259a91c
--- /dev/null
+++ b/aewl/util.h
@@ -0,0 +1,76 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewl_util_h
+#define _btco_aewl_util_h
+
+#include <ncurses.h>
+
+/* Prints a string of text on the given window at the given position,
+ * interpreting the '&' escape character as meaning "set the next character's
+ * attribute to attr2. Rest of string is printed in attr1 */
+void aewl_util_mvwaddstr(WINDOW *w, int y, int x, int attr1, int attr2,
+ const char *str);
+
+/* Calculates the printed length of the given string, considering the
+ * '&' escape character. So the printed length of "&Abc" is 3, although
+ * strlen() would return 4. */
+int aewl_util_strlen_esc(const char *str);
+
+/* Clears the given rectangle by overwriting it with spaces*/
+void aewl_util_erase(WINDOW *win, int x, int y, int w, int h);
+
+/* Draws a box on the given window with the given coordinates. x, y are the
+ * top-left, h,w are the dimensions. */
+void aewl_util_drawbox(WINDOW *win, int x, int y, int w, int h);
+
+/* Draws a horizontal line in the given window, from (x0, y) to (x1, y).
+ * The leftmost character will be lc, the middle will be filled with mc
+ * characters, and the rightmost character will be rc */
+void aewl_util_drawline_h(WINDOW *w, int x0, int x1, int y,
+ int lc, int mc, int rc);
+
+/* Draws a vertical line in the given window, from (x, y0) to (x, y1).
+ * The topmost character will be tc, the middle will be filled with mc
+ * characters, and the bottommost character will be bc */
+void aewl_util_drawline_v(WINDOW *w, int x, int y0, int y1,
+ int tc, int mc, int bc);
+
+
+/* Prints the given string as in addstr(), except that no more than n
+ * characters will be printed */
+void aewl_util_addnstr(WINDOW *w, int n, const char *str);
+
+
+#endif
+
diff --git a/aewl/widget.c b/aewl/widget.c
new file mode 100644
index 0000000..c851dc5
--- /dev/null
+++ b/aewl/widget.c
@@ -0,0 +1,48 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "widget.h"
+
+void aewl_widget_fill_defaults(AewlWidget *w) {
+ w->win = stdscr;
+ w->x = w->y = 0;
+ w->width = w->height = 0;
+ w->shortcut = 0;
+ w->focusable = false;
+
+ w->fn_repaint = NULL;
+ w->fn_handlekey = NULL;
+ w->fn_destroy = NULL;
+}
+
+
diff --git a/aewl/widget.h b/aewl/widget.h
new file mode 100644
index 0000000..b20e22b
--- /dev/null
+++ b/aewl/widget.h
@@ -0,0 +1,86 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewl_widget_h
+#define _btco_aewl_widget_h
+
+#include <ncurses.h>
+#include <stdbool.h>
+
+struct AewlForm_;
+
+/* definition of AewlWidget */
+struct AewlWidget_;
+struct AewlWidget_ {
+ WINDOW *win; /* the window where this widget draws
+ * itself. This is set when the
+ * widget is added to a form, you don't
+ * need to assign it explicitly. */
+
+ struct AewlForm_ *form; /* the form to which this widget belongs. This
+ * is set when the widget is added to a form */
+
+ int x, y, width, height; /* widget position and dimensions */
+
+ int shortcut; /* shortcut key to focus widget */
+ bool focusable; /* indicates whether the widget can
+ * receive input focus */
+
+ struct AewlWidget_* next; /* link to next widget in chain; for use
+ * when chaining widgets in a linked list */
+
+ /* functions */
+
+ /* repaints widget onscreen. <focused> indicates whether the widget
+ * is focused or not. Can be NULL (does not repaint) */
+ void (*fn_repaint)(struct AewlWidget_ *self, bool focused);
+
+ /* handles a keypress directed to this widget. Returns a result code
+ * (an integer value, plain and simple). This function pointer
+ * can be NULL (handles no keys, result code returned always 0) */
+ int (*fn_handlekey)(struct AewlWidget_ *self, int ch);
+
+ /* destroys the widget */
+ void (*fn_destroy)(struct AewlWidget_ *self);
+};
+typedef struct AewlWidget_ AewlWidget;
+
+/* There is no function to create a widget out of thin air. This is like
+ * an "abstract class" if you want to think about it that way. */
+
+/* Fills in (in-place) the default values for the fields of the given widget.
+ * This function is to be called from concrete widget implementation code */
+void aewl_widget_fill_defaults(AewlWidget* w);
+
+#endif
+
diff --git a/bores/Makefile b/bores/Makefile
new file mode 100644
index 0000000..71815f1
--- /dev/null
+++ b/bores/Makefile
@@ -0,0 +1,64 @@
+# Copyright (c) 2003 Bruno T. C. de Oliveira
+#
+# LICENSE INFORMATION:
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Copyright (c) 2002 Bruno T. C. de Oliveira
+#
+# INFORMAÇÕES DE LICENÇA:
+# Este programa é um software de livre distribuição; você pode
+# redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+# Public License, conforme publicado pela Free Software Foundation,
+# pela versão 2 da licença ou qualquer versão posterior.
+#
+# Este programa é distribuído na esperança de que ele será útil
+# aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+# a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+# QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+# License para obter mais detalhes (uma cópia acompanha este
+# programa, armazenada no arquivo COPYING).
+
+SOURCES=$(wildcard *.c)
+HEADERS=$(filter-out bores.h,$(wildcard *.h))
+OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
+
+CFLAGS+=-Wall
+
+all: libbores.a bores.h
+
+bores.h:
+ @echo >bores.h
+ @echo "/* ------ GENERATED FILE. DO NOT EDIT -------- */" >>bores.h
+ @echo "/* THIS FILE IS OVERWRITTEN EVERY TIME YOU */" >>bores.h
+ @echo "/* BUILD THE BORES LIBRARY. */" >>bores.h
+ @echo "/* */" >>bores.h
+ @echo "/* Copyright (c) 2003 Bruno T. C. de Oliveira. */" >>bores.h
+ @echo "/* All rights reserved. */" >>bores.h
+ for i in $(HEADERS); do echo "#include \"$$i\"" >>bores.h; done
+
+libbores.a: $(OBJECTS)
+ rm -f libbores.a
+ ar -r libbores.a $(OBJECTS)
+
+.depends: $(SOURCES) $(HEADERS)
+ $(CC) $(CFLAGS) -MM $(SOURCES) >.depends
+
+-include .depends
+
+clean:
+ rm -f *.o .depends libbores.a bores.h
+
+.PHONY: clean all
+
+
diff --git a/bores/autod.c b/bores/autod.c
new file mode 100644
index 0000000..2ab7b48
--- /dev/null
+++ b/bores/autod.c
@@ -0,0 +1,58 @@
+#include "autod.h"
+#include <stdio.h>
+
+void do_autod_register(AutodRegistryNode *head, void **ptr,
+ autod_destructor_t destr) {
+ AutodRegistryNode *newnode = (AutodRegistryNode*)
+ malloc(sizeof(AutodRegistryNode));
+ newnode->ptr = ptr;
+ newnode->destructor = destr;
+ newnode->next = head->next;
+ head->next = newnode;
+
+ *(ptr) = 0; /* zero the pointer to make sure it doesn't contain
+ * garbage */
+}
+
+void do_autod_assign(AutodRegistryNode *head, void **ptr, void *newvalue) {
+ AutodRegistryNode *n;
+
+ if (*ptr) {
+ /* destroy previous value before attributing a new value; for that,
+ * we must look for the corresponding node in the registry */
+ n = head->next;
+ while (n) {
+ if (n->ptr == ptr) {
+ /* got it, call destructor */
+ (*(n->destructor))(*ptr);
+ break;
+ }
+ }
+
+ if (!n) {
+ /* not found: abort */
+ fprintf(stderr, "autod: FATAL ERROR: attempt to assign to\n"
+ "unregistered pointer.\n\n");
+ abort();
+ }
+ }
+
+ /* we are clear to assign a new value */
+ *ptr = newvalue;
+}
+
+void do_autod_cleanup(AutodRegistryNode *head, void *ignore_ptr) {
+ AutodRegistryNode *n = head->next;
+ AutodRegistryNode *next;
+
+ while (n) {
+ if (*(n->ptr) && *(n->ptr) != ignore_ptr)
+ (*(n->destructor))(*(n->ptr)); /* call destructor */
+
+ next = n->next;
+ free(n); /* free the node */
+
+ n = next; /* advance to next */
+ }
+}
+
diff --git a/bores/autod.h b/bores/autod.h
new file mode 100644
index 0000000..6645d6f
--- /dev/null
+++ b/bores/autod.h
@@ -0,0 +1,122 @@
+/*
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+/* This is a set of convenience macros and functions for enabling
+ * "automatic" destruction of dynamically-allocated objects when
+ * exitting the scope of a function. This is especially useful
+ * in functions that can return at several points, and it would be
+ * difficult to keep track of what is allocated at which point in order
+ * to free everything correctly.
+ *
+ * The philosophy is this:
+ *
+ * void my_func(...) {
+ * Brick *my_brick;
+ * Camel *my_camel;
+ * char *my_string;
+ *
+ * autod_begin;
+ * autod_register(my_brick, brick_destroy); // also sets my_brick = NULL
+ * autod_register(my_camel, camel_destroy); // also sets my_camel = NULL
+ * autod_register(my_string, free); // also sets my_string = NULL
+ *
+ * // do what you want with my_brick, my_camel and my_string
+ *
+ * if (somefunc() == ERROR)
+ * autod_return; // this takes care of destroying my_brick,
+ * // my_camel and my_string, by calling the
+ * // destructor function specified when registering
+ *
+ * // do more stuff with my_brick, my_camel, my_string
+ *
+ * autod_return; // don't forget to put this at the end
+ * }
+ *
+ * Sometimes you will want to return a registered object, which means
+ * that it should not be free'd (the caller will get ownership of the
+ * object). In this case, use autod_return_obj(v), and all registered
+ * pointers will be free'd except v, which will be returned.
+ *
+ * Also, notice you should never do:
+ *
+ * my_camel = other_camel;
+ *
+ * Because the original value of my_camel will be lost and will not
+ * be free'd (memory leak). Instead, you should do:
+ *
+ * if (my_camel) camel_destroy(my_camel);
+ * my_camel = other_camel;
+ *
+ * Since this occurs often, a convenience macro is provided:
+ *
+ * autod_assign(my_camel, other_camel);
+ *
+ * This takes care of destroying the old camel before assigning the new one
+ * (this sentence really sounds weird).
+ */
+
+
+#ifndef btco_bores_autod_h
+#define btco_bores_autod_h
+
+#include <stdlib.h>
+
+typedef void (*autod_destructor_t)(void*);
+
+typedef struct AutodRegistryNode_ {
+ void **ptr;
+ autod_destructor_t destructor;
+ struct AutodRegistryNode_ *next;
+} AutodRegistryNode;
+
+#define autod_begin AutodRegistryNode autodregistry_head; \
+ autodregistry_head.next = 0
+
+#define autod_register(ptr, d) do_autod_register(&autodregistry_head, \
+ (void**)&ptr, (autod_destructor_t)d)
+
+#define autod_return_value(v) { do_autod_cleanup(&autodregistry_head, 0); return v; }
+#define autod_return_obj(v) { do_autod_cleanup(&autodregistry_head, (void*)v); return v; }
+#define autod_return { do_autod_cleanup(&autodregistry_head, 0); return; }
+#define autod_assign(ptr, newvalue) do_autod_assign(&autodregistry_head, \
+ (void**)&ptr, newvalue)
+
+void do_autod_register(AutodRegistryNode *head, void **ptr,
+ autod_destructor_t destr);
+
+void do_autod_assign(AutodRegistryNode *head, void **ptr, void *newvalue);
+
+void do_autod_cleanup(AutodRegistryNode *head, void *ignore_ptr);
+
+
+#endif
+
+
diff --git a/bores/bores.h b/bores/bores.h
new file mode 100644
index 0000000..2d1eb21
--- /dev/null
+++ b/bores/bores.h
@@ -0,0 +1,38 @@
+/*
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "autod.h"
+#include "darray.h"
+#include "defs.h"
+#include "hashdict.h"
+#include "kurses.h"
+#include "util.h"
+
diff --git a/bores/darray.c b/bores/darray.c
new file mode 100644
index 0000000..a461aeb
--- /dev/null
+++ b/bores/darray.c
@@ -0,0 +1,137 @@
+/*
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#include "darray.h"
+#include "util.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DEFAULT_CAPACITY 20
+
+#define CAPACITY_AHEAD 20 /* when a value is assigned to an out of bounds
+ item, this is how far beyond it the capacity
+ grows. */
+
+struct DArray_ {
+ int len;
+ int cap;
+ void **items;
+ void (*value_destroyer)(void*);
+};
+
+DArray* darray_create() {
+ return darray_create_ex(DEFAULT_CAPACITY, NULL);
+}
+
+DArray* darray_create_ex(int cap, void (*vd)(void*)) {
+ DArray* da = zalloc(sizeof(DArray));
+
+ da->len = 0;
+ da->cap = (cap > 0) ? cap : DEFAULT_CAPACITY;
+ da->items = zalloc(sizeof(void*) * da->cap);
+ da->value_destroyer = vd;
+
+ return da;
+}
+
+void darray_destroy(DArray* da) {
+ int i;
+ if (!da) return;
+ if (da->value_destroyer) {
+ /* call value destroyer for each item */
+ for (i = 0; i < da->len; i++)
+ if (da->items[i]) (*da->value_destroyer)(da->items[i]);
+ }
+
+ /* free up the items array then the darray itself */
+ sfree(da->items);
+ sfree(da);
+}
+
+int darray_len(DArray* da) {
+ /* this one is really complicated */
+ return da->len;
+}
+
+void* darray_get(DArray* da, int i) {
+ return (i >= 0 && i < da->len) ? da->items[i] : NULL;
+}
+
+void darray_set(DArray* da, int i, const void *v) {
+ if (i < 0) {
+ fprintf(stderr, "*** FATAL ERROR ***\n"
+ "Attempt to darray_set with negative index %d\n", i);
+ abort();
+ }
+ else if (i >= da->len) {
+ da->cap = i + CAPACITY_AHEAD;
+ da->items = srealloc(da->items, sizeof(void*) * da->cap);
+
+ /* grow array while assignung NULLs to all newly included items */
+ while (i >= da->len) da->items[da->len++] = NULL;
+ }
+ else {
+ /* call value destroyer if there was anything there */
+ if (da->items[i] && da->value_destroyer)
+ (*da->value_destroyer)(da->items[i]);
+ }
+
+ da->items[i] = (void*) v;
+}
+
+void* darray_snatch(DArray *da, int i) {
+ void *v;
+ if (i >= 0 && i < da->len) {
+ v = da->items[i];
+ da->items[i] = NULL;
+ return v;
+ }
+ else return NULL;
+}
+
+void darray_append(DArray *da, const void *v) {
+ darray_set(da, da->len, v);
+}
+
+void darray_remove(DArray *da, int i) {
+ if (i < 0 || i >= da->len) return;
+ if (da->items[i] && da->value_destroyer)
+ (*da->value_destroyer)(da->items[i]);
+
+ while (i < da->len - 1) {
+ da->items[i] = da->items[i+1];
+ i++;
+ }
+
+ da->len--;
+}
+
diff --git a/bores/darray.h b/bores/darray.h
new file mode 100644
index 0000000..2523914
--- /dev/null
+++ b/bores/darray.h
@@ -0,0 +1,95 @@
+/*
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef btco_bores_darray_h
+#define btco_bores_darray_h
+
+/* opaque dynamic array type */
+struct DArray_;
+typedef struct DArray_ DArray;
+
+/* creates a new dynamic array of default initial capacity and no
+ * value destroyer function. */
+DArray* darray_create();
+
+/* creates a new dynamic array of initial capacity cap (must be positive)
+ * and value destroyer function f. The value destroyer is a function
+ * called whenever a value stored in the array must be destroyed or
+ * will be overwritten. */
+DArray* darray_create_ex(int cap, void (*vd)(void*));
+
+/* destroys the given dynamic array. The value destroyer function will
+ * be called for all non-NULL values in the array at this point. */
+void darray_destroy(DArray*);
+
+/* obtains the length of a dynamic array. This is NOT the capacity. The
+ * length is how many elements are actually there. You should not be
+ * interested in the capacity, since it is internally managed. */
+int darray_len(DArray*);
+
+/* obtains the item from the array whose index is i. If i is out of
+ * bounds, NULL is returned (and no error occurs). PLEASE notice
+ * that this function is for consultation only, the value will still
+ * be owned by the darray (and thus can be destroyed at any moment
+ * by the value destroyer function). If you want to gain ownership
+ * over the value you get, use darray_snatch instead. */
+void* darray_get(DArray*, int i);
+
+/* sets the value of item index i to NULL, without calling the value
+ * destroyer function for it. Returns the value the item had before
+ * being set to NULL. If the index i is out of bounds, nothing is done
+ * and NULL is returned. */
+void* darray_snatch(DArray*, int i);
+
+/* sets the value of item index i to v. If the item had a non-NULL value
+ * before, the value destroyer function will be called for it before
+ * it is overwritten. If the index is out of bounds and positive, the
+ * array will be dynamically expanded to make it valid. If it is
+ * negative a fatal error occurs.
+ *
+ * If i is out of bounds and v is NULL, this function does absolutely
+ * nothing, because expanding the array to put a NULL value is
+ * really the same as just leaving it as it is, because darray_get
+ * returns NULL if you pass it an out-of-bounds index.
+ *
+ * Whenever the array expands, the newly created items are set to NULL,
+ * that is, they are not left with trash in them.
+ */
+void darray_set(DArray*, int i, const void *v);
+
+/* Same as darray_set(da, darray_len(da), v) */
+void darray_append(DArray*, const void *v);
+
+/* removes item i from array, shifting all others up */
+void darray_remove(DArray*, int i);
+
+#endif
+
diff --git a/bores/defs.h b/bores/defs.h
new file mode 100644
index 0000000..8993ee9
--- /dev/null
+++ b/bores/defs.h
@@ -0,0 +1,43 @@
+/*
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef btco_bores_defs_h
+#define btco_bores_defs_h
+
+/* libbores version number. Please keep the following defines in sync!
+ * If the major version is X.Y.Z, the INT version will be 10000X + 100Y + Z
+ * Thus if the version is 0.5.13, the int version would be 513. */
+#define BORES_VERSION_STR "0.6.1"
+#define BORES_VERSION_INT 601
+
+#endif
+
+
diff --git a/bores/hashdict.c b/bores/hashdict.c
new file mode 100644
index 0000000..165815e
--- /dev/null
+++ b/bores/hashdict.c
@@ -0,0 +1,222 @@
+/*
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "hashdict.h"
+#include "util.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#define DEFAULT_BUCKET_COUNT 30
+
+struct Node_ { /* each node in the linked lists */
+ char *key;
+ const void *value;
+
+ struct Node_ *next;
+};
+typedef struct Node_ Node;
+
+struct HashDict_ {
+ int bucketcount; /* how many buckets in this dictionary */
+ Node *bucketheads;/* array of head nodes, one for each bucket.
+ * The data in the head node means nothing. The linked
+ * list begins with the node that head->next points to */
+ void (*value_destroyer)(void*); /* function called to destroy values.
+ * If NULL, no function is called */
+};
+
+/* declaration of private functions -----------------------------*/
+static void _destroy_node(HashDict *hd, Node* n);
+static int _which_bucket(const char *key, int bucketcount);
+static Node* _node_lookup(HashDict *hd,
+ const char *key); /* warning: this function has counter-intuitive
+ (but useful) beheavior (q.v.) */
+/* --------------------------------------------------------------*/
+
+HashDict* hashdict_create_ex(int bucketcount, void (*value_destroyer)(void*)) {
+ HashDict *hd = zalloc(sizeof(struct HashDict_));
+ hd->bucketcount = bucketcount;
+ hd->value_destroyer = value_destroyer;
+ hd->bucketheads = zalloc(sizeof(Node) * bucketcount);
+
+ return hd;
+}
+
+HashDict* hashdict_create(void) {
+ return hashdict_create_ex(DEFAULT_BUCKET_COUNT, 0);
+}
+
+void hashdict_destroy(HashDict* hd) {
+ int i; Node *n;
+ if (!hd) return;
+
+ /* destroy all nodes */
+ for (i = 0; i < hd->bucketcount; i++) {
+ while ( (n = hd->bucketheads[i].next) ) {
+ /* delete node n */
+ hd->bucketheads[i].next = n->next;
+ _destroy_node(hd, n);
+ }
+ }
+
+ free(hd->bucketheads);
+ free(hd);
+}
+
+void* hashdict_get(HashDict *hd, const char *key) {
+ Node *n = _node_lookup(hd, key);
+
+ /* be mindful that _node_lookup returns the node BEFORE
+ the one we are looking for */
+ return (void*) (n->next ? n->next->value : 0);
+}
+
+void hashdict_set(HashDict *hd, const char *key, const void *value) {
+ Node *n;
+ if (!value) { hashdict_unset(hd, key); return; }
+
+ n = _node_lookup(hd, key);
+ if (n->next) {
+ /* node already exists: replace value */
+ if (hd->value_destroyer) (*hd->value_destroyer)((void*)n->next->value);
+ n->next->value = value;
+ }
+ else {
+ /* does not exist yet: append to list */
+ Node *newnode = zalloc(sizeof(Node));
+ newnode->key = sstrdup(key);
+ newnode->value = value;
+ newnode->next = NULL;
+ n->next = newnode;
+ }
+}
+
+bool hashdict_unset(HashDict *hd, const char *key) {
+ Node *n = _node_lookup(hd, key);
+ if (n->next) {
+ _destroy_node(hd, n->next);
+ n->next = n->next->next;
+ return true; /* found and deleted */
+ }
+ return false; /* not found */
+}
+
+void hashdict_write(HashDict *hd, FILE *f, void (*value_writer)(void*, FILE*)) {
+ /* TODO */
+}
+
+HashDict* hashdict_read(HashDict *hd, FILE *f, void* (*valuereader)(FILE*)) {
+ /* TODO */
+ return NULL;
+}
+
+HashDictIt hashdict_it_start(HashDict *hd) {
+ HashDictIt it;
+
+ /* put iterator before beginning */
+ it.pastend = false;
+ it.key = it.value = NULL;
+ it.dict = hd;
+ it.nextbucket = 0;
+ it.nextnode = NULL;
+
+ return it;
+}
+
+bool hashdict_it_advance(HashDictIt *hdi) {
+ if (hdi->pastend) return false; /* already at the end */
+
+ if (hdi->nextnode) {
+ hdi->key = ((Node*)hdi->nextnode)->key;
+ hdi->value = ((Node*)hdi->nextnode)->value;
+ hdi->nextnode = ((Node*)hdi->nextnode)->next;
+ }
+ else {
+ /* go to next nonempty bucket */
+ HashDict *hd = hdi->dict;
+ int i = hdi->nextbucket;
+ while (i < hd->bucketcount && !hd->bucketheads[i].next) i++;
+
+ if (i < hd->bucketcount) {
+ /* we know hd->buckethead[i].next is not NULL */
+ hdi->key = hd->bucketheads[i].next->key;
+ hdi->value = hd->bucketheads[i].next->value;
+ hdi->nextbucket = i+1;
+ hdi->nextnode = hd->bucketheads[i].next->next;
+ }
+ else {
+ /* passed the end */
+ hdi->key = hdi->value = NULL; /* for safety */
+ hdi->pastend = true;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* private functions ----------------------------------------------------- */
+static Node* _node_lookup(HashDict *hd, const char *key) {
+ /* ATTENTION: return value is not the node you are looking for;
+ * rather, it is the node BEFORE it. This is useful for a variety
+ * of reasons, including node deletion and appending */
+
+ /* returns ptr to node n such that n->next->key is equal to <key>.
+ * If not found, returns the last node in the bucket that <key>
+ * hashes into. (in this case, the 'next' field of the return
+ * value will be NULL, since it is the last node in a list). */
+ Node *n = &(hd->bucketheads[_which_bucket(key, hd->bucketcount)]);
+ while (n->next && strcmp(n->next->key, key)) n = n->next;
+ return n;
+}
+
+static void _destroy_node(HashDict *hd, Node* n) {
+ if (n) {
+ if (hd->value_destroyer && n->value)
+ (*hd->value_destroyer)((void*)n->value);
+ zfree(&n->key);
+ free(n);
+ }
+}
+
+static int _which_bucket(const char *key, int bucketcount) {
+ /* this function computes the hashcode of the given key
+ * in a dictionary with <bucketcount> buckets. If str is non-NULL
+ * and bucketcount > 0, the return value is guaranteed to be
+ * nonnegative and smaller than bucketcount. */
+
+ /* FIXME: write a serious hash function. This one is laughable. */
+
+ int x = 0;
+ while (*key) x += *(key++);
+ return x % bucketcount;
+}
+
diff --git a/bores/hashdict.h b/bores/hashdict.h
new file mode 100644
index 0000000..e8be9f3
--- /dev/null
+++ b/bores/hashdict.h
@@ -0,0 +1,139 @@
+/*
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+/* hashdict.h
+ * A general purpose dictionary implemented by means of a hashtable.
+ * This dictionary maps string keys to values of arbitrary type.
+ * It allows the specification of a value-destroy function that will
+ * be called whenever values are to be overwritten or deleted.
+ *
+ * Restrictions:
+ *
+ * - keys must be strings of positive length, and must of course be
+ * unique.
+ *
+ * - values may not be NULL, because NULL is used as a
+ * return value to indicate absense of keys, and because when writing/reading
+ * to a file handling of NULL values would complicate things.
+ *
+ * Copyright (c) 2003 by Bruno T. C. de Oliveira
+ * All rights reserved.
+ *
+ * 2003.01.07
+ */
+
+#ifndef btco_bores_hashdict_h
+#define btco_bores_hashdict_h
+
+#include <stdio.h>
+#include <stdbool.h>
+
+/* opaque dictionary handle */
+struct HashDict_;
+typedef struct HashDict_ HashDict;
+
+/* iterator type */
+struct HashDictIt_ {
+ /* indicates whether this iterator is past the end of the dictionary */
+ bool pastend;
+
+ /* key and value of entry iterator is currently pointing to. Read only. */
+ const char *key;
+ const void *value;
+
+ /* internal data. Do not tamper with. */
+ HashDict* dict; /* the dictionary this iterator pertains to */
+ int nextbucket; /* the next bucket to be visited after this one ends */
+ void *nextnode; /* the next node in this bucket to be visited. If
+ NULL, next advancement will cause the iterator
+ to go to the next nonempty bucket */
+};
+typedef struct HashDictIt_ HashDictIt;
+
+/* Creates a new dictionary with default bucketcount and no value destroyer
+ * function. */
+HashDict* hashdict_create(void);
+
+/* Creates a new dictionary given bucketcount and a value destroyer function.*/
+HashDict* hashdict_create_ex(int bucketcount, void (*valuedestroyer)(void*));
+
+/* Destroy a dictionary previously created by hashdict_create */
+void hashdict_destroy(HashDict* hd);
+
+/* Look up key <key> in the dictionary. Returns the associated value,
+ * or NULL if the value is not found. */
+void* hashdict_get(HashDict* hd, const char *key);
+
+/* Sets the value associated to the given key. If the key already exists,
+ * the value associated to it will be overwritten (and the value-
+ * destroyer function will be called); otherwise, a new entry will be added.
+ *
+ * As a convenience, if value is NULL, this function is equivalent
+ * to hashdict_unset(hd, key) */
+void hashdict_set(HashDict* hd, const char *key, const void *value);
+
+/* Removes from the dictionary the entry whose key is <key>, if it exists.
+ * If it was removed, returns true; if it was not found, returns false */
+bool hashdict_unset(HashDict* hd, const char *key);
+
+/* Writes dictionary to file f in a binary format. valuewriter is a
+ * function that will be used to write the values onto the stream. */
+void hashdict_write(HashDict *hd, FILE *f, void (*valuewriter)(void*, FILE*));
+
+/* Reads a dictionary previously saved with hashdict_write.
+ * valuereader is a function that will be used to read values from
+ * the stream. If valuereader returns NULL at any time, this
+ * function will interpret it as an error. If this happens,
+ * or if any other error occurs, this function will return NULL. */
+HashDict* hashdict_read(HashDict *hd, FILE *f, void* (*valuereader)(FILE*));
+
+/* Returns a new hash dict iterator that points BEFORE the first entry
+ * in the dictionary. Iterators are lightweight objects, i.e.,
+ * they don't need to be deallocated. That's why there is no
+ * hashdict_it_destroy function.
+ *
+ * Please note that the iterator returned is not in a valid position
+ * (it is BEFORE the start). You must advance it before using the value.
+ * This behavior is useful because you can write neat loops:
+ *
+ * it = hashdict_it_start(hd);
+ * while (hashdict_it_advance(it)) {
+ * // use it->key and it->value here
+ * }
+ */
+HashDictIt hashdict_it_start(HashDict *hd);
+
+/* Advances the given iterator. Returns true if advancement was successful,
+ * or false if the end of the dictionary was reached. */
+bool hashdict_it_advance(HashDictIt *hdi);
+
+#endif
+
diff --git a/bores/kurses.c b/bores/kurses.c
new file mode 100644
index 0000000..619c963
--- /dev/null
+++ b/bores/kurses.c
@@ -0,0 +1,293 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "kurses.h"
+#include "util.h"
+#include <ncurses.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* mapping between color codes and curses pairs and attributes:
+ *
+ * color pair depends on the three least significant bits of the foreground
+ * and background. If a pair is (fg, bg),
+ * let FG = fg % 8 (i.e. the three least significant bits)
+ * let BG = bg % 8
+ *
+ * the curses pair for it will be BG * 8 + (7 - FG)
+ *
+ * Valid curses pairs are 1..63, but the color (7, 0) maps to pair number 0.
+ * This is no problem, because (7, 0) is the default color so it needs
+ * no curses color pair.
+ *
+ * After the color pair is selected, the most significant bit of
+ * fg and bg are used to activate A_BOLD and A_BLINK attributes.
+ */
+
+/* --------- internal data and declarations of private functions ---------- */
+
+/* current foreground and background colors */
+static int cur_fg, cur_bg;
+
+/* Given a pair of color codes, returns the corresponding curses pair */
+static int kurses_pair_for(int fg, int bg);
+
+/* node type for the saved screen linked list (see below) */
+struct SavedScreenNode_ {
+ WINDOW *win; /* the curses window that holds the screenshot */
+ struct SavedScreenNode_* next;
+};
+typedef struct SavedScreenNode_ SavedScreenNode;
+
+/* Stack of saved screens, implemented as a linked list */
+SavedScreenNode *sss_top; /* sss = 'saved screen stack' */
+
+/* -------------- implementation of public functions ---------------------- */
+
+void kurses_init() {
+ int fg, bg;
+
+ initscr(); /* enter screen-oriented mode */
+ raw(); /* don't treat Ctrl+C, etc. as special. */
+ noecho(); /* don't echo typed characters back to terminal */
+ keypad(stdscr, TRUE); /* convert ugly escape sequences to more
+ * palatable curses KEY_* codes */
+
+ cur_fg = 7;
+ cur_bg = 0;
+ sss_top = NULL;
+
+ if (!has_colors()) {
+ fprintf(stderr, "*** Fatal error: Terminal has no color support.\n");
+ exit(1);
+ }
+
+ start_color();
+
+ /* initialize all curses pairs */
+ for (fg = 0; fg < 8; fg++) for (bg = 0; bg < 8; bg++) {
+ int pair = kurses_pair_for(fg, bg);
+ if (!pair) continue; /* don't try to initialize pair 0,
+ * that corresponds to color (7, 0). */
+
+ init_pair(pair, fg, bg);
+ }
+
+ clear();
+ refresh();
+}
+
+void kurses_finalize() {
+ clear();
+ refresh();
+ endwin();
+}
+
+void kurses_color(int fg, int bg) {
+ int pair;
+
+ if (fg < 0) fg = cur_fg;
+ if (bg < 0) bg = cur_bg;
+
+ /* see what color pair corresponds to fg, bg */
+ pair = kurses_pair_for(fg, bg);
+
+ /* if that maps to 0, just reset attribute; otherwise set color pair */
+ if (pair) attrset(COLOR_PAIR(pair));
+ else attrset(A_NORMAL);
+
+ /* now turn on A_BOLD and A_BLINK attribute as indicated by the most
+ * significant bit of fg and bg, respectively */
+ if (fg & 0x08) attron(A_BOLD);
+ if (bg & 0x08) attron(A_BLINK);
+}
+
+/* Same as kurses_color(attr >> 4, attr & 0x0F) */
+void kurses_color_at(int attr) {
+ kurses_color(attr >> 4, attr & 0x0F);
+}
+
+int kurses_width() {
+ int maxy, maxx;
+ getmaxyx(stdscr, maxy, maxx);
+ return maxx;
+}
+
+int kurses_height() {
+ int maxy, maxx;
+ getmaxyx(stdscr, maxy, maxx);
+ return maxy;
+}
+
+int kurses_pos_valid(int x, int y) {
+ return (x >= 0 && x < kurses_width() &&
+ y >= 0 && y < kurses_height());
+}
+
+int kurses_move(int x, int y) {
+ if (!kurses_pos_valid(x, y)) return 0;
+ move(y, x);
+ return 1;
+}
+
+int kurses_line_input(char *buf, int buf_size) {
+ return kurses_line_input_ex(buf, buf_size, NULL, 0);
+}
+
+int kurses_line_input_ex(char *buf, int buf_size, int *skeys, int flags) {
+ int pos = 0;
+ int ch;
+ const int *p;
+
+ while (1) {
+ refresh();
+ ch = getch();
+ if (ch < 0) continue;
+
+ /* first check if character is in skeys */
+ if ( (p = skeys) ) while (*p) if (*(p++) == ch) return -ch;
+
+ /* proceed to normal handling */
+ switch (ch) {
+ case 10: buf[pos] = 0; return 1; /* confirm input */
+ case 3:
+ case 7:
+ case 27: *buf = 0; return 0; /* cancel input */
+ case KEY_BACKSPACE: case 8: case 127: /* backspace */
+ if (pos > 0) { --pos; addch('\b'); addch(' '); addch('\b'); }
+ break;
+ case 'U' - 0x40: /* kill */
+ while (pos--) { addch('\b'); addch(' '); addch('\b'); }
+ pos = 0;
+ break;
+ default:
+ if (pos <= buf_size - 2 && printable_char(ch)) {
+ /* buffer not full (remember to reserve a byte for the NULL),
+ * and character is not a control character: append it */
+ buf[pos++] = ch;
+ addch((flags & KURSES_LI_HIDE) ? '*' : ch);
+ }
+ }
+ }
+}
+
+void draw_window(int x0, int y0, int w, int h, const char *title) {
+ int x, y, x1, y1;
+ int gr_ch[3][3];
+
+ gr_ch[0][0]=ACS_ULCORNER, gr_ch[0][1]=ACS_HLINE, gr_ch[0][2]=ACS_URCORNER;
+ gr_ch[1][0]=ACS_VLINE, gr_ch[1][1]=' ', gr_ch[1][2]=ACS_VLINE;
+ gr_ch[2][0]=ACS_LLCORNER, gr_ch[2][1]=ACS_HLINE, gr_ch[2][2]=ACS_LRCORNER;
+
+ x1 = x0 + w - 1;
+ y1 = y0 + h - 1;
+
+ for (y = y0; y < y0 + h; y++)
+ for (x = x0; x < x0 + w; x++)
+ if (!kurses_move(x, y)) continue;
+ else addch(gr_ch [(y == y0) ? 0 : (y == y1) ? 2 : 1]
+ [(x == x0) ? 0 : (x == x1) ? 2 : 1]);
+
+ if (title) if (kurses_move(x0 + w/2 - strlen(title) / 2, y0)) addstr(title);
+ kurses_move(x0 + 1, y0 + 1);
+}
+
+void draw_centered_window(int w, int h, const char *title, int *x, int *y) {
+ int x0 = (kurses_width() - w) / 2;
+ int y0 = (kurses_height() - h) / 2;
+ if (x) *x = x0 + 1;
+ if (y) *y = y0 + 1;
+
+ draw_window(x0, y0, w, h, title);
+}
+
+void draw_hline(int x0, int y0, int w,
+ int left_endpt, int interim, int right_endpt)
+{
+ int x;
+ if (!kurses_move(x0, y0)) return;
+ for (x = x0; x < x0 + w; x++)
+ addch( (x == x0) ? left_endpt :
+ (x == x0 + w - 1) ? right_endpt : interim);
+}
+
+void draw_vline(int x0, int y0, int h,
+ int upper_endpt, int interim, int lower_endpt) {
+ int y;
+ if (!kurses_move(x0, y0)) return;
+ for (y = y0; y < y0 + h; y++) {
+ kurses_move(x0, y);
+ addch( (y == y0) ? upper_endpt :
+ (y == y0 + h - 1) ? lower_endpt : interim);
+ }
+}
+
+void push_screen(void) {
+ SavedScreenNode *n = zalloc(sizeof(SavedScreenNode));
+ n->win = newwin(0,0,0,0);
+ overwrite(stdscr, n->win);
+ n->next = sss_top;
+
+ sss_top = n;
+}
+
+void restore_screen(void) {
+ if (!sss_top) {
+ /* if there are no saved screens, just clear the screen and return.
+ * Doesn't make much sense, but beats doing nothing or segfaulting. */
+ erase();
+ return;
+ }
+
+ overwrite(sss_top->win, stdscr);
+ touchwin(stdscr);
+}
+
+void pop_screen(void) {
+ SavedScreenNode *newtop;
+ if (!sss_top) return;
+
+ newtop = sss_top->next;
+ free(sss_top);
+ sss_top = newtop;
+}
+
+/* -------------- implementation of private functions --------------------- */
+static int kurses_pair_for(int fg, int bg) {
+ fg &= 0x07; bg &= 0x07; /* only keep the three least significant bits */
+ return (bg << 3) + (7 - fg);
+}
+
+
+
diff --git a/bores/kurses.h b/bores/kurses.h
new file mode 100644
index 0000000..0f40cde
--- /dev/null
+++ b/bores/kurses.h
@@ -0,0 +1,133 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_bores_kurses_h
+#define _btco_bores_kurses_h
+
+/* Color codes are 4-bit values. The bits are SBGR, where B, G and R are
+ * the blue, green and red components, and the S bit is the bold attribute
+ * for foreground colors, or the blink attribute for background colors.
+ *
+ * Refer to the implementation file for information about how color code
+ * pairs are mapped to curses pairs */
+
+/* Initializes curses, sets screen mode, initializes pairs, and so on. */
+void kurses_init();
+
+/* Finalize curses */
+void kurses_finalize();
+
+/* Sets the active color to (fg, bg). Either can be -1, in which case
+ * the previous value is kept. */
+void kurses_color(int fg, int bg);
+
+/* Same as kurses_color(attr >> 4, attr & 0x0F) */
+void kurses_color_at(int attr);
+
+/* Returns the screen width */
+int kurses_width();
+
+/* Returns the screen height */
+int kurses_height();
+
+/* Moves cursor to position (x, y). Returns true if motion was successful,
+ * false if given coordinates are invalid */
+int kurses_move(int x, int y);
+
+/* Returns whether position x,y falls within screen bounds */
+int kurses_pos_valid(int x, int y);
+
+/* Reads a line of input from the keyboard, storing read characters in
+ * <buf>. At most <buf_size> characters are stored in the buffer.
+ * Interprets the "backspace" and "kill" keys. Returns true if the
+ * user ended input by pressing RETURN; false if the user cancelled
+ * input by means of ESC, Ctrl+C or Ctrl+G. */
+int kurses_line_input(char *buf, int buf_size);
+
+/* Does the same as kurses_line_input, but with an extended feature:
+ * the array skeys of ints specifies special keys; when the user
+ * presses any of those special keys, input will stop and the negative
+ * of the value of the key will be returned. Character '\0' must
+ * be at the end the skeys array. The flags parameter are an OR'ed
+ * combination of the KURSES_LI_* flags defined below.
+ *
+ * If the user cancels input, returns 0.
+ * If the user confirms input without pressing any special key,
+ * returns 1.
+ */
+int kurses_line_input_ex(char *buf, int buf_size, int* skeys, int flags);
+ #define KURSES_LI_HIDE 1 /* echoes '*' instead of characters */
+
+/* Draws a window with the specified position, dimensions and title.
+ * Uses currently active color. After operation, cursor will be
+ * placed on top-left character of CLIENT AREA of window. */
+void draw_window(int x, int y, int w, int h, const char *title);
+
+/* Draws a window centered onscreen. Returns in *x and *y the position
+ * of the top-left character cell within the window's CLIENT AREA,
+ * which is also where the cursor is located after the call. */
+void draw_centered_window(int w, int h, const char *title, int *x, int *y);
+
+/* Draws a horizontal row of <w> characters starting at position x0, y0.
+ * The first character draw will be left_endpt; then character interim
+ * will be drawn w-2 times, then the right_endpt will be drawn. */
+void draw_hline(int x0, int y0, int w,
+ int left_endpt, int interim, int right_endpt);
+
+/* Same idea as draw_hline, but draws a vertical line instead. */
+void draw_vline(int x0, int y0, int h,
+ int upper_endpt, int interim, int lower_endpt);
+
+/* Saves a snapshot of the screen (stdscr) onto an internal stack.
+ * That snapshot can be later restored through a call to
+ * pop_screen */
+void push_screen(void);
+
+/* Restores a screen snapshot previously saved with push_screen.
+ * Does NOT pop it from the stack: it will stay there in case
+ * you want to restore it again. To discard it from the stack,
+ * call pop_screen(void)
+ *
+ * Does NOT call refresh; you will have to do that yourself. */
+void restore_screen(void);
+
+/* Removes the top of the internal screen snapshot stack.
+ * Does NOT paint the removed snapshot to the screen. If you
+ * want that, call restore_screen() _before_ calling
+ * pop_screen */
+void pop_screen(void);
+
+
+#endif
+
diff --git a/bores/util.c b/bores/util.c
new file mode 100644
index 0000000..828f4a6
--- /dev/null
+++ b/bores/util.c
@@ -0,0 +1,270 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "util.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+char *dstrset(char **ptr, const char *new_value) {
+ if (*ptr) free(*ptr);
+ return (*ptr = new_value ? sstrdup(new_value) : 0);
+}
+
+void *zalloc(int bytes) {
+ void *buf;
+
+ if (bytes <= 0) return 0;
+
+ if (!(buf = malloc(bytes))) {
+ fprintf(stderr, "*** FATAL ERROR ***\n"
+ "zalloc failed to allocate memory.\n"
+ "Request size: %d bytes.\n\nSorry.\n", bytes);
+ abort();
+ }
+
+ memset(buf, 0, bytes);
+ return buf;
+}
+
+char* sstrdup(const char *s) {
+ char *r;
+ if (!s) return 0;
+
+ if ( !(r = strdup(s)) ) {
+ fprintf(stderr, "*** FATAL ERROR ***\n"
+ "sstrdup failed to allocate memory.\n");
+ abort();
+ }
+ return r;
+}
+
+void *srealloc(void *buf, int newsize) {
+ if (!buf) return zalloc(newsize);
+ if (!(buf = realloc(buf, newsize))) {
+ fprintf(stderr, "*** FATAL ERROR ***\n"
+ "srealloc failed to reallocate memory.\n"
+ "Request size: %d bytes.\n\nSorry.\n", newsize);
+ abort();
+ }
+ return buf;
+}
+
+int minimum(int a, int b) { return (a < b) ? a : b; }
+int maximum(int a, int b) { return (a > b) ? a : b; }
+double minimum_d(double a, double b) { return (a < b) ? a : b; }
+double maximum_d(double a, double b) { return (a > b) ? a : b; }
+
+
+int printable_char(int ch) {
+ if (ch < 0 || ch > 255) return 0; /* not in char range */
+ if (ch <= 31 || ch == 127) return 0; /* control character */
+ return 1;
+}
+
+char *str_fit_ex(const char *orig, int size, int padch) {
+ char *s; char *p;
+ if (size <= 0) return 0;
+
+ p = s = zalloc(size + 1);
+ while (p - s < size)
+ *(p++) = (*orig) ? *(orig++) : padch;
+
+ *p = 0;
+ return s;
+}
+
+char *str_fit(const char *orig, int size) {
+ return str_fit_ex(orig, size, ' ');
+}
+
+float timeval_dif(const struct timeval* a, const struct timeval* b) {
+ long to_remove;
+ float af, bf;
+ if (a->tv_sec > b->tv_sec) to_remove = b->tv_sec;
+ else to_remove = a->tv_sec;
+
+ af = (float)(a->tv_sec - to_remove) + a->tv_usec / 1000000.0f;
+ bf = (float)(b->tv_sec - to_remove) + b->tv_usec / 1000000.0f;
+ return af - bf;
+}
+
+void fsavestr(const char *str, FILE *f) {
+ int len = strlen(str);
+
+ fwrite(&len, sizeof(int), 1, f);
+ while (*str) fputc(*(str++), f);
+}
+
+char *floadstr(FILE *f) {
+ char *str, *p; int len;
+
+ fread(&len, sizeof(int), 1, f);
+
+ p = str = zalloc(len + 1);
+ while (len--) *(p++) = fgetc(f);
+
+ return str;
+}
+
+void interval_intersect(int a0, int a1, int b0, int b1, int *c0, int *c1) {
+ *c0 = maximum(a0, b0);
+ *c1 = minimum(a1, b1);
+}
+
+void interval_intersect_d(double a0, double a1, double b0, double b1,
+ double *c0, double *c1) {
+ *c0 = maximum_d(a0, b0);
+ *c1 = minimum_d(a1, b1);
+}
+
+void sort_two(int v0, int v1, int *r0, int *r1) {
+ if (v0 <= v1) {
+ if (r0) *r0 = v0;
+ if (r1) *r1 = v1;
+ }
+ else {
+ if (r0) *r0 = v1;
+ if (r1) *r1 = v0;
+ }
+}
+
+char *dsprintf(const char *fmt, ...) {
+ /* this function was adapted from the example provided in
+ * Linux man page for printf(3) */
+ int n, size = 100;
+ char *p;
+ va_list ap;
+
+ p = zalloc(size);
+
+ while (1) {
+ /* Try to print in the allocated space. */
+ va_start(ap, fmt); n = vsnprintf (p, size, fmt, ap); va_end(ap);
+
+ /* If that worked, return the string. */
+ if (n > -1 && n < size) return p;
+
+ /* Else try again with more space. */
+ if (n > -1) /* glibc 2.1 */
+ size = n+1; /* precisely what is needed */
+ else /* glibc 2.0 */
+ size *= 2; /* twice the old size */
+
+ p = srealloc (p, size);
+ }
+}
+
+void sfree(void *ptr) {
+ if (ptr) free(ptr);
+}
+
+void zfree(char **str) {
+ if (*str) {
+ free(*str);
+ *str = 0;
+ }
+}
+
+char *freadline(FILE *f) {
+ return freadline_ex((void*)f, (int(*)(void*)) fgetc);
+}
+
+char *freadline_ex(void *fh, int (*readch)(void*)) {
+ int size = 64;
+ char *buf;
+ int i;
+ char ch;
+
+ /* read in the first character */
+ ch = readch(fh);
+ if (ch < 0) return NULL;
+
+ /* allocate buffer */
+ buf = zalloc(size + 1);
+ i = 0;
+
+ /* store and read over and over until \n or EOF */
+ while (ch != '\n' && ch != -1) {
+ buf[i++] = ch;
+ if (i >= size) buf = srealloc(buf, 1 + (size += size));
+
+ ch = readch(fh);
+ }
+
+ buf[i] = 0; /* we know we can write on buf[i] because we know i <= size,
+ * (remember that buf has capacity is size + 1) */
+ return buf;
+}
+
+char *strtrim(const char *s) {
+ char *t, *u;
+ while (*s == ' ' || *s == '\t' || *s == '\n') s++;
+ t = sstrdup(s);
+ u = t + strlen(t) - 1;
+ while (u >= t && (*u == ' ' || *u == '\t' || *u == '\n')) u--;
+ u[1] = 0;
+ return t;
+}
+
+char *dstrcat(const char *s, const char *t) {
+ char *u = zalloc(1 + (s ? strlen(s) : 0) + (t ? strlen(t) : 0));
+ if (s) strcpy(u, s);
+ if (t) strcat(u, t);
+ return u; /* zalloc zeroes out the buffer, so even if s == t == NULL,
+ * u will be a single '\0', which is a correct result. */
+}
+
+void chr2hex(int c, char* ret) {
+ static char hs[] = "0123456789abcdef";
+
+ if (c <= 0) c = 0;
+ if (c >= 256) c = 255;
+
+ ret[0] = hs[c / 16];
+ ret[1] = hs[c % 16];
+ ret[2] = 0;
+}
+
+static int hex_digit_val(char c) {
+ if (c >= '0' && c <= '9') return c - '0';
+ else if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F') return c - 'A' + 10;
+ else return 0;
+}
+
+int hex2chr(const char *hex) {
+ return hex_digit_val(hex[0]) * 16 + hex_digit_val(hex[1]);
+}
+
diff --git a/bores/util.h b/bores/util.h
new file mode 100644
index 0000000..8a5605a
--- /dev/null
+++ b/bores/util.h
@@ -0,0 +1,169 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef bores_util_h
+#define bores_util_h
+#include <sys/time.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#define FMTCALL(x, f) { char *fmts = dsprintf x; f; zfree(&fmts); }
+
+/* If (*ptr) { free(*ptr), *ptr = NULL; }. Then, makes *ptr =
+ * strdup(new_value) if new_value is not NULL. Returns the value *ptr
+ * after the assignment. */
+char *dstrset(char **ptr, const char *new_value);
+
+/* If *str { free(*str); *str = NULL; } */
+void zfree(char **str);
+
+/* If ptr, free(ptr) */
+void sfree(void *ptr);
+
+/* Does what you expect */
+int minimum(int a, int b);
+
+/* Duh. */
+int maximum(int a, int b);
+
+/* Does what you expect */
+double minimum_d(double a, double b);
+
+/* Duh. */
+double maximum_d(double a, double b);
+
+/* Allocates memory like malloc, with the following differences: (1) exits
+ * program with a fatal error if memory cannot be allocated; (2) zeroes
+ * out the newly allocated buffer before returning. This function returns
+ * NULL if and only if bytes <= 0. */
+void *zalloc(int bytes);
+
+/* If <buf> is not null, works just like realloc. If <buf> is null,
+ * calls zalloc instead of realloc. Returns a pointer to the reallocated
+ * (or newly allocated) buffer; NULL if and only if newsize <= 0. */
+void *srealloc(void *buf, int newsize);
+
+/* Returns true if the passed character ch is printable */
+int printable_char(int ch);
+
+/* Returns a dynamically allocated string whose length is exactly <size>.
+ * If strlen(<orig>) <= <size>, returned string is a copy of <orig>
+ * padded with padch characters. If strlen(<orig>) > <size>, returned
+ * string is a copy of <orig> clipped to <size>.
+ *
+ * Returns NULL if the fitting cannot be done because <size> is invalid */
+char *str_fit_ex(const char *orig, int size, int padch);
+
+/* Convenience function that calls
+ * str_fit_ex(orig, size, ' ') */
+char *str_fit(const char *orig, int size);
+
+/* Returns difference in seconds between the two passed
+ * timevals. This difference will be positive if a > b,
+ * negative if a < b, or zero if a and b are the same */
+float timeval_dif(const struct timeval* a, const struct timeval* b);
+
+/* Saves the string pointed to by <str> in the file <f>, in a format
+ * that can later be read back by floadstr() */
+void fsavestr(const char *str, FILE *f);
+
+/* Loads a string from file <f>, as saved by fsavestr(). Returns a dynamically
+ * allocated string (which the caller must free) or NULL if there is an
+ * error. */
+char *floadstr(FILE *f);
+
+/* Calculates the intersection of two integer intervals with inclusive
+ * endpoints. Interval [a0..a1], where a0 <= a1, is intersected with
+ * interval [b0..b1], where b0 <= b1. The resulting interval [c0..c1] is
+ * stored in variables c0 and c1. An empty interval is denoted by
+ * c0 > c1. */
+void interval_intersect(int a0, int a1, int b0, int b1, int *c0, int *c1);
+
+/* Same as interval_intersect, but with doubles */
+void interval_intersect_d(double a0, double a1, double b0, double b1,
+ double *c0, double *c1);
+
+/* Does what you expect */
+int minimum(int a, int b);
+
+/* Duh. */
+int maximum(int a, int b);
+
+/* Sorts the two values v0 and v1, returning the result in variables
+ * r0 and r1. Return value has the property that *r0 <= *r1 */
+void sort_two(int v0, int v1, int *r0, int *r1);
+
+/* Behaves like sprintf, but returns a dynamically allocated string
+ * as large as necessary to contain the results. Uses zalloc to allocate
+ * memory, so memory allocation does not fail (a fatal error is produced
+ * if system has insufficient memory) */
+char *dsprintf(const char *fmt, ...);
+
+/* Reads a full line from file f, allocating space as needed to contain it.
+ * Returns a dynamically allocated buffer, or NULL if EOF was read before
+ * any characters could be read in. The \n will NOT be included in the
+ * returned string (unlike fgets()). */
+char *freadline(FILE *f);
+
+/* Same as freadline, but in this function you specify a custom function
+ * to read characters from your stream, and the file handle is opaque
+ * (that is, can be anything you want, not necessarily a FILE*).
+ * When this function needs a character, it will call the readch
+ * function passing it the file handle fh, and expect it to return
+ * the next character on the stream or -1 if EOF is reached. */
+char *freadline_ex(void *fh, int (*readch)(void*));
+
+/* Returns a new string that results from removing leading and trailing
+ * spaces from string s */
+char *strtrim(const char *s);
+
+/* Like strdup(), but aborts the program with a fatal error if memory
+ * cannot be allocated (rather than return NULL as strdup() does).
+ * Also, if s is NULL, returns NULL rather than segfaulting (which is
+ * what strdup() does). */
+char *sstrdup(const char *s);
+
+/* Returns a dynamically allocated string that results from the concatenation
+ * of strings s and t. NULL parameters are NOT an error and will be
+ * equivalent to empty strings. */
+char *dstrcat(const char *s, const char *t);
+
+/* Returns the hexadecimal representation of the given character
+ * as a two-digit hexadecimal number stored in the array ret, which
+ * must be of size 3. A trailing \0 is appended. The hex2chr function
+ * does the reverse */
+void chr2hex(int c, char* ret);
+int hex2chr(const char *hex);
+
+#endif
+
diff --git a/chtr.c b/chtr.c
new file mode 100644
index 0000000..ce91158
--- /dev/null
+++ b/chtr.c
@@ -0,0 +1,61 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include <ncurses.h>
+
+#include "chtr.h"
+
+int chtr_a2c(unsigned char aewan_ch) {
+ int mappings[32] = {
+ ACS_CKBOARD,
+ ACS_HLINE,
+ ACS_VLINE,
+ ACS_ULCORNER,
+ ACS_TTEE,
+ ACS_URCORNER,
+ ACS_LTEE,
+ ACS_PLUS,
+ ACS_RTEE,
+ ACS_LLCORNER,
+ ACS_BTEE,
+ ACS_LRCORNER,
+ ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD,
+ ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD,
+ ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD,
+ ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD, ACS_CKBOARD
+ };
+
+ if (aewan_ch < 32) return mappings[aewan_ch];
+ return aewan_ch;
+}
+
diff --git a/chtr.h b/chtr.h
new file mode 100644
index 0000000..d872d33
--- /dev/null
+++ b/chtr.h
@@ -0,0 +1,67 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewan_chtr_h
+#define _btco_aewan_chtr_h
+
+/* Since a control character may never be in a cell, aewan uses some
+ * values in the 0-31 range to represent special characters. It does
+ * not use the curses ACS_ characters because their values are
+ * implementation dependent and are all greater than 255 (so they would
+ * not fit in an unsigned char anyway)
+ *
+ * The chtr in "chtr.h" stands for "character translation"
+ */
+
+/* aewan special values for a cell's character */
+#define AEWAN_CHAR_HLINE 1
+#define AEWAN_CHAR_VLINE 2
+#define AEWAN_CHAR_ULCORNER 3
+#define AEWAN_CHAR_TTEE 4
+#define AEWAN_CHAR_URCORNER 5
+#define AEWAN_CHAR_LTEE 6
+#define AEWAN_CHAR_PLUS 7
+#define AEWAN_CHAR_RTEE 8
+#define AEWAN_CHAR_LLCORNER 9
+#define AEWAN_CHAR_BTEE 10
+#define AEWAN_CHAR_LRCORNER 11
+#define AEWAN_CHAR_CKBOARD 12
+
+/* Maps an aewan character to a curses character. This is not restricted
+ * to special characters: regular characters will map to themselves.
+ * Control characters that do not have special meanings will map
+ * to some bogus (but printable) character. */
+int chtr_a2c(unsigned char aewan_ch);
+
+#endif
+
diff --git a/clipboard.c b/clipboard.c
new file mode 100644
index 0000000..bef9eaa
--- /dev/null
+++ b/clipboard.c
@@ -0,0 +1,70 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include <stdio.h>
+
+#include "clipboard.h"
+#include "document.h"
+#include "psd.h"
+
+void clear_clipboard(void) {
+ if (_clipboard) layer_destroy(_clipboard);
+ _clipboard = NULL;
+}
+
+void copy_sel_to_clipboard(void) {
+ int selwidth, selheight;
+ int x0, x1, y0, y1;
+
+ /* calculate selection dimensions */
+ get_norm_sel(&x0, &y0, &x1, &y1);
+ selwidth = x1 - x0 + 1;
+ selheight = y1 - y0 + 1;
+
+ /* size clipboard appropriately */
+ clear_clipboard();
+ _clipboard = layer_create("clipboard", selwidth, selheight);
+
+ /* blit from currently active document layer to clipboard */
+ layer_blit(_doc->layers[_lyr], x0, y0, selwidth, selheight,
+ _clipboard, 0, 0);
+
+}
+
+void paste_clipboard(void) {
+ if (!_clipboard) return;
+ layer_blit(_clipboard, 0, 0, _clipboard->width, _clipboard->height,
+ _doc->layers[_lyr], _x, _y);
+}
+
+
diff --git a/clipboard.h b/clipboard.h
new file mode 100644
index 0000000..52df428
--- /dev/null
+++ b/clipboard.h
@@ -0,0 +1,52 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_clipboard_h
+#define _btco_aewan_clipboard_h
+
+#include "layer.h"
+
+/* Clears clipboard, freeing its memory */
+void clear_clipboard(void);
+
+/* Copies the current selection to the clipboard layer */
+void copy_sel_to_clipboard(void);
+
+/* Pastes the clipboard contents onto the document,
+ placing the top-left corner at the position of the cursor */
+void paste_clipboard(void);
+
+#endif
+
+
diff --git a/colordlg.c b/colordlg.c
new file mode 100644
index 0000000..599b64c
--- /dev/null
+++ b/colordlg.c
@@ -0,0 +1,96 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+#include <ncurses.h>
+
+#include "colordlg.h"
+#include "psd.h"
+
+static void paint_dlg(void) {
+ int x0, y0; int i, j;
+ char hexdigit[] = "0123456789abcdef";
+
+ kurses_color(7, 0);
+ draw_centered_window(39, 21, "Choose Color", &x0, &y0);
+
+ /* draw bg color knob */
+ kurses_color(12, 0);
+ kurses_move(x0 + 4 + 2 * _bg, y0);
+ addch('b');
+
+ /* draw fg color knob */
+ kurses_color(10, 0);
+ kurses_move(x0, y0 + 2 + _fg);
+ addch('f');
+
+ /* draw horizontal (bg) ruler */
+ kurses_color(7, 0);
+ kurses_move(x0 + 4, y0 + 1);
+ addstr("0 1 2 3 4 5 6 7 8 9 a b c d e f");
+
+ /* draw vertical (fg) ruler */
+ for (i = 0; i < 16; i++) {
+ kurses_move(x0 + 2, y0 + 2 + i);
+ addch(hexdigit[i]);
+ }
+
+ /* draw squares */
+ for (i = 0; i < 16; i++) {
+ kurses_move(x0 + 4, y0 + 2 + i);
+ for (j = 0; j < 16; j++) {
+ kurses_color(i, j);
+ addstr("Aa");
+ }
+ }
+
+ /* place cursor on selected square */
+ kurses_move(x0 + 4 + 2 * _bg, y0 + 2 + _fg);
+}
+
+void show_color_dlg(void) {
+ int ch;
+ while (1) {
+ paint_dlg();
+ refresh();
+ ch = getch();
+ switch (ch) {
+ case 27: case 3: case 7: case 10: return;
+ case KEY_UP: if (--_fg < 0) _fg = 15; break;
+ case KEY_DOWN: if (++_fg >= 16) _fg = 0; break;
+ case KEY_LEFT: if (--_bg < 0) _bg = 15; break;
+ case KEY_RIGHT: if (++_bg >= 16) _bg = 0; break;
+ }
+ }
+}
+
diff --git a/colordlg.h b/colordlg.h
new file mode 100644
index 0000000..39e225b
--- /dev/null
+++ b/colordlg.h
@@ -0,0 +1,44 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_colordlg_h
+#define _btco_aewan_colordlg_h
+
+/* invokes the "set color" dialog, which allows the user to interactively
+ * modify the globals _fg and _bg. Only returns after the user has quit
+ * the dialog box. Does not restore screen. */
+void show_color_dlg(void);
+
+#endif
+
diff --git a/commands.h b/commands.h
new file mode 100644
index 0000000..ed7fb3d
--- /dev/null
+++ b/commands.h
@@ -0,0 +1,83 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef btco_aewan_commands_h
+#define btco_aewan_commands_h
+
+/* Commands are what make the editor _do_ things. The keys that the
+ * user presses are translated to commands and then fed into
+ * the main command-handling function handle_command() */
+#define COMMAND_UNDEFINED 0 /* special value used as error flag */
+#define COMMAND_ADD_LAYER_DEFAULTS 1
+#define COMMAND_ADD_LAYER_SPECIFY 2
+#define COMMAND_SET_FOREGROUND 3
+#define COMMAND_SET_BACKGROUND 4
+#define COMMAND_SHOW_COLOR_DLG 5
+#define COMMAND_TOGGLE_INSERT 6
+#define COMMAND_SHOW_HELP_DLG 7
+#define COMMAND_LOAD_FILE 8
+#define COMMAND_SAVE_FILE 9
+#define COMMAND_SAVE_FILE_AS 10
+#define COMMAND_EDIT_META 11
+#define COMMAND_MOVE_LEFT 12
+#define COMMAND_MOVE_RIGHT 13
+#define COMMAND_MOVE_UP 14
+#define COMMAND_MOVE_DOWN 15
+#define COMMAND_CARRIAGE_RETURN 16
+#define COMMAND_PAGE_DOWN 17
+#define COMMAND_PAGE_UP 18
+#define COMMAND_START_OF_LINE 19
+#define COMMAND_END_OF_LINE 20
+#define COMMAND_FAST_LEFT 21
+#define COMMAND_FAST_RIGHT 22
+#define COMMAND_PICK_COLOR 23
+#define COMMAND_TINT_CELL 24
+#define COMMAND_TOGGLE_SELECTION 25
+#define COMMAND_CANCEL 26
+#define COMMAND_SHOW_LAYER_DLG 27
+#define COMMAND_NEXT_LAYER 28
+#define COMMAND_PREV_LAYER 29
+#define COMMAND_DUP_LAYER 30
+#define COMMAND_RENAME_LAYER 31
+#define COMMAND_TOGGLE_LINE_MODE 32
+#define COMMAND_TOGGLE_COMPOSITE 33
+#define COMMAND_QUIT 34
+#define COMMAND_NEW_FILE 35
+#define COMMAND_SHOW_ABOUT_DLG 36
+#define COMMAND_RESIZE_LAYER 37
+#define COMMAND_TOTAL 38 /* total number of commands
+ (for sizing arrays and the like) */
+
+#endif
+
+
diff --git a/configure b/configure
new file mode 100755
index 0000000..3fc5552
--- /dev/null
+++ b/configure
@@ -0,0 +1,4558 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="aewan"
+ac_unique_file="aewan.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP EXESUF LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#AC_CONFIG_HEADER([config.h])
+
+# Checks for programs.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Check for the standard stdbool header file
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5
+echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6
+if test "${ac_cv_header_stdbool_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <stdbool.h>
+#ifndef bool
+# error bool is not defined
+#endif
+#ifndef false
+# error false is not defined
+#endif
+#if false
+# error false is not 0
+#endif
+#ifndef true
+# error true is not defined
+#endif
+#if true != 1
+# error true is not 1
+#endif
+#ifndef __bool_true_false_are_defined
+# error __bool_true_false_are_defined is not defined
+#endif
+
+ struct s { _Bool s: 1; _Bool t; } s;
+
+ char a[true == 1 ? 1 : -1];
+ char b[false == 0 ? 1 : -1];
+ char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+ char d[(bool) -0.5 == true ? 1 : -1];
+ bool e = &s;
+ char f[(_Bool) -0.0 == false ? 1 : -1];
+ char g[true];
+ char h[sizeof (_Bool)];
+ char i[sizeof s.t];
+
+int
+main ()
+{
+ return !a + !b + !c + !d + !e + !f + !g + !h + !i;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdbool_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdbool_h=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6
+echo "$as_me:$LINENO: checking for _Bool" >&5
+echo $ECHO_N "checking for _Bool... $ECHO_C" >&6
+if test "${ac_cv_type__Bool+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((_Bool *) 0)
+ return 0;
+if (sizeof (_Bool))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type__Bool=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type__Bool=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5
+echo "${ECHO_T}$ac_cv_type__Bool" >&6
+if test $ac_cv_type__Bool = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STDBOOL_H 1
+_ACEOF
+
+fi
+
+
+# Checks for libraries.
+
+echo "$as_me:$LINENO: checking for initscr in -lncurses" >&5
+echo $ECHO_N "checking for initscr in -lncurses... $ECHO_C" >&6
+if test "${ac_cv_lib_ncurses_initscr+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char initscr ();
+int
+main ()
+{
+initscr ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_ncurses_initscr=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ncurses_initscr=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_initscr" >&5
+echo "${ECHO_T}$ac_cv_lib_ncurses_initscr" >&6
+if test $ac_cv_lib_ncurses_initscr = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNCURSES 1
+_ACEOF
+
+ LIBS="-lncurses $LIBS"
+
+else
+ { { echo "$as_me:$LINENO: error: Can't find ncurses library. Install it first." >&5
+echo "$as_me: error: Can't find ncurses library. Install it first." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking for gzopen in -lz" >&5
+echo $ECHO_N "checking for gzopen in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_gzopen+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gzopen ();
+int
+main ()
+{
+gzopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_z_gzopen=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_gzopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzopen" >&5
+echo "${ECHO_T}$ac_cv_lib_z_gzopen" >&6
+if test $ac_cv_lib_z_gzopen = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+ LIBS="-lz $LIBS"
+
+else
+ { { echo "$as_me:$LINENO: error: Can't find zlib library. Install it first." >&5
+echo "$as_me: error: Can't find zlib library. Install it first." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+# Checks for header files.
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+for ac_header in zlib.h fcntl.h limits.h stdlib.h string.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists. ##
+## ------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset x;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *ccp;
+ char **p;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ ccp = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++ccp;
+ p = (char**) ccp;
+ ccp = (char const *const *) p;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ }
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_const=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for mode_t" >&5
+echo $ECHO_N "checking for mode_t... $ECHO_C" >&6
+if test "${ac_cv_type_mode_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((mode_t *) 0)
+ return 0;
+if (sizeof (mode_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_mode_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_mode_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5
+echo "${ECHO_T}$ac_cv_type_mode_t" >&6
+if test $ac_cv_type_mode_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define mode_t int
+_ACEOF
+
+fi
+
+
+# Checks for library functions.
+
+
+
+for ac_func in atexit strdup strerror
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Checks for cygwin
+echo "$as_me:$LINENO: checking for cygwin OSTYPE" >&5
+echo $ECHO_N "checking for cygwin OSTYPE... $ECHO_C" >&6
+if test x$OSTYPE == xcygwin; then
+ EXESUF=.exe
+
+ echo "$as_me:$LINENO: result: it is cygwin, using .exe" >&5
+echo "${ECHO_T}it is cygwin, using .exe" >&6
+else
+ echo "$as_me:$LINENO: result: not cygwin" >&5
+echo "${ECHO_T}not cygwin" >&6
+fi
+
+ ac_config_files="$ac_config_files Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
+t quote
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output. A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@EXESUF@,$EXESUF,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..e887013
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,42 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_INIT([aewan])
+AC_CONFIG_SRCDIR([aewan.c])
+#AC_CONFIG_HEADER([config.h])
+
+# Checks for programs.
+AC_PROG_CC
+
+# Check for the standard stdbool header file
+AC_HEADER_STDBOOL
+
+# Checks for libraries.
+AC_CHECK_LIB([ncurses], [initscr], [],
+ AC_MSG_ERROR([Can't find ncurses library. Install it first.]))
+AC_CHECK_LIB([z], [gzopen], [],
+ AC_MSG_ERROR([Can't find zlib library. Install it first.]))
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([zlib.h fcntl.h limits.h stdlib.h string.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_MODE_T
+
+# Checks for library functions.
+AC_CHECK_FUNCS([atexit strdup strerror])
+
+# Checks for cygwin
+AC_MSG_CHECKING([for cygwin OSTYPE])
+if test x$OSTYPE == xcygwin; then
+ AC_SUBST(EXESUF, [.exe])
+ AC_MSG_RESULT([it is cygwin, using .exe])
+else
+ AC_MSG_RESULT([not cygwin])
+fi
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+
diff --git a/debug_aewl.c b/debug_aewl.c
new file mode 100644
index 0000000..a47b09a
--- /dev/null
+++ b/debug_aewl.c
@@ -0,0 +1,121 @@
+#include "debug_aewl.h"
+
+#include "aewl/aewl.h"
+#include "aewl/form.h"
+#include "aewl/button.h"
+#include "aewl/listbox.h"
+#include "aewl/field.h"
+#include "aewl/label.h"
+
+#include "keys.h"
+
+#include <ncurses.h>
+#include <stdbool.h>
+
+static int curses_attr_for_pair(int fg, int bg, bool bold) {
+ short int cp = bg * 8 + 7 - fg;
+ if (!cp) return bold ? A_BOLD : A_NORMAL;
+ return COLOR_PAIR(cp) | (bold ? A_BOLD : 0);
+}
+
+void debug_aewl() {
+ char *s = filedlg_show("Test Dialog");
+ clear();
+
+ printw("Answer: '%s'\n", s);
+ getch();
+}
+
+void debug_aewl_OLD() {
+ AewlWidget *b1, *b2, *b3, *lbl;
+ AewlListBox *lb;
+ AewlWidget *fld;
+ AewlForm *f;
+ int r;
+
+ AewlAttrSettings ats = {
+ {
+ curses_attr_for_pair(7, 0, false), /* text */
+ curses_attr_for_pair(7, 0, true), /* text focus */
+ curses_attr_for_pair(1, 0, false), /* text shortcut */
+ curses_attr_for_pair(1, 0, true) /* text shortcut focus */
+ },
+
+ {
+ curses_attr_for_pair(7, 4, false), /* button */
+ curses_attr_for_pair(7, 2, true), /* button focus */
+ curses_attr_for_pair(1, 4, false), /* button shortcut */
+ curses_attr_for_pair(1, 2, true) /* button shortcut focus */
+ },
+
+ {
+ curses_attr_for_pair(7, 0, false), /* frame */
+ curses_attr_for_pair(7, 0, true), /* frame focus */
+ curses_attr_for_pair(1, 0, false), /* frame shortcut */
+ curses_attr_for_pair(1, 0, true) /* frame shortcut focus */
+ },
+
+ {
+ curses_attr_for_pair(7, 0, false), /* field */
+ curses_attr_for_pair(7, 0, true), /* field focus */
+ curses_attr_for_pair(7, 4, false), /* field selection */
+ curses_attr_for_pair(7, 1, true) /* field selection focus */
+ },
+
+ curses_attr_for_pair(0, 0, true) /* field pad char */
+ };
+
+ aewl_init(&ats);
+
+ clear();
+ refresh();
+ f = aewl_form_create(stdscr);
+
+ b1 = aewl_button_create(10, 10, 20, KEY_ALT_A, 1, "Button &Ay One");
+ b2 = aewl_button_create(10, 12, 20, KEY_ALT_B, 2, "Button &Bee Two");
+ b3 = aewl_button_create(10, 14, 20, KEY_ALT_C, 3, "Button &Cee Three");
+ lb = (AewlListBox*)
+ aewl_listbox_create(40, 10, 30, 10, KEY_ALT_L, "My &List", 123);
+ fld = aewl_field_create(10, 20, 20, KEY_ALT_T, 4, "Test field");
+ lbl = aewl_label_create(4, 20, -1, "&Text:");
+
+ aewl_listbox_add(lb, "Ut queant laxis");
+ aewl_listbox_add(lb, "Resonare fibris");
+ aewl_listbox_add(lb, "Mira gestorum");
+ aewl_listbox_add(lb, "Famuli tuorum");
+ aewl_listbox_add(lb, "Solve polluti");
+ aewl_listbox_add(lb, "Labii reatum");
+ aewl_listbox_add(lb, "Sancte Ioannes");
+ aewl_listbox_add(lb, "Lacrymosa dies illa");
+ aewl_listbox_add(lb, "Qua resurget ex favilla");
+ aewl_listbox_add(lb, "Iudicandus homo reus");
+ aewl_listbox_add(lb, "Huic ergo parce Deus");
+ aewl_listbox_add(lb, "Pie iesu domine");
+ aewl_listbox_add(lb, "Dona eis requiem");
+ aewl_listbox_add(lb, "Stabat mater dolorosa");
+ aewl_listbox_add(lb, "Iuxta crucem lacrymosam");
+ aewl_listbox_add(lb, "Dum pendebat filius");
+ aewl_listbox_add(lb, "Quis est homo qui non fleret");
+ aewl_listbox_add(lb, "Matrem Christi se videret");
+ aewl_listbox_add(lb, "In tanto suplicio?");
+
+ aewl_form_add_widget(f, b1);
+ aewl_form_add_widget(f, b2);
+ aewl_form_add_widget(f, b3);
+ aewl_form_add_widget(f, (AewlWidget*) lb);
+ aewl_form_add_widget(f, fld);
+ aewl_form_add_widget(f, lbl);
+
+ aewl_form_paint(f, true);
+ while (0 == (r = aewl_form_dispatch_key(f, getch())));
+ aewl_form_destroy(f);
+
+ clear();
+ refresh();
+ printw("Selected value %d", r);
+ getch();
+
+ clear();
+ refresh();
+}
+
diff --git a/debug_aewl.h b/debug_aewl.h
new file mode 100644
index 0000000..cb396fb
--- /dev/null
+++ b/debug_aewl.h
@@ -0,0 +1,7 @@
+#ifndef btco_aewn_debug_aewl_h
+#define btco_aewn_debug_aewl_h
+
+void debug_aewl();
+
+#endif
+
diff --git a/document.c b/document.c
new file mode 100644
index 0000000..cfd34c0
--- /dev/null
+++ b/document.c
@@ -0,0 +1,227 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "document.h"
+
+#define DEFAULT_NOM_WIDTH 80
+#define DEFAULT_NOM_HEIGHT 25
+
+Document *document_create(void) {
+ Document *doc = (Document*) zalloc(sizeof(Document));
+ return doc;
+}
+
+void document_destroy(Document *doc) {
+ int i;
+ if (!doc) return;
+ if (doc->layers) {
+ for (i = 0; i < doc->layer_count; i++)
+ free(doc->layers[i]);
+ free(doc->layers);
+ }
+
+ dstrset(&doc->metainfo, 0);
+ free(doc);
+}
+
+void document_add_layer(Document *doc, Layer *layer) {
+ (doc->layers = srealloc(doc->layers, (++doc->layer_count) * sizeof(Layer*)))
+ [doc->layer_count-1] = layer;
+}
+
+void document_insert_layer(Document *doc, int i, Layer *layer) {
+ int j;
+ if (i < 0) i = 0;
+ if (i > doc->layer_count) i = doc->layer_count;
+
+ /* first reallocate the array (and increment doc->layer_count) */
+ doc->layers = srealloc(doc->layers, (++doc->layer_count) * sizeof(Layer*));
+
+ /* now shift layers to make room */
+ for (j = doc->layer_count - 1; j > i; j--)
+ doc->layers[j] = doc->layers[j-1];
+
+ /* position i is now free */
+ doc->layers[i] = layer;
+}
+
+void document_del_layer(Document *doc, int i) {
+ if (i < 0 || i >= doc->layer_count) return;
+
+ /* FIXME: this doesn't realloc the layers array, so it does not
+ * reclaim memory allocated by document_add_layer. */
+ layer_destroy(doc->layers[i]);
+ for (; i < doc->layer_count - 1; i++)
+ doc->layers[i] = doc->layers[i+1];
+
+ doc->layer_count--;
+}
+
+void document_get_nom_dim(Document *doc, int *w, int *h) {
+ if (!doc || !doc->layer_count) {
+ if (w) *w = DEFAULT_NOM_WIDTH;
+ if (h) *h = DEFAULT_NOM_HEIGHT;
+ }
+ else {
+ if (w) *w = doc->layers[0]->width;
+ if (h) *h = doc->layers[0]->height;
+ }
+}
+
+void document_save(Document *doc, AeFile *f) {
+ int i;
+
+ aeff_write_header(f, "Aewan Document v1");
+ aeff_write_int(f, "layer-count", doc->layer_count);
+ aeff_write_string(f, "meta-info", doc->metainfo ? doc->metainfo : "");
+
+ for (i = 0; i < doc->layer_count; i++)
+ layer_save(doc->layers[i], f);
+
+ aeff_write_footer(f, "Aewan Document v1");
+}
+
+Document *document_load_from(const char *filename) {
+ static char buf[2];
+ int i;
+ Document *d = NULL;
+
+ FILE *f = fopen(filename, "r");
+ if (!f) {
+ char *msg = dsprintf("%s: %s", filename, strerror(errno));
+ aeff_set_error(msg);
+ zfree(&msg);
+ return NULL;
+ }
+
+ /* get first 2 bytes from file and close it */
+ for (i = 0; i < 2; i++) buf[i] = fgetc(f);
+ fclose(f);
+
+ if (!strncmp(buf, "DO", 2)) {
+ /* old format (binary). */
+ d = document_load_OLD(f = fopen(filename, "r"));
+ if (!d) aeff_set_error("Malformed (old) binary format");
+ fclose(f);
+ return d;
+ }
+ else if (!strncmp(buf, "\037\213", 2)) {
+ /* gzip format: assume new format (aeff) */
+ AeFile *aeff = aeff_open(filename, 'r');
+ if (!aeff) return NULL;
+ return document_load(aeff);
+ }
+ else {
+ aeff_set_error("Unrecognized file format.");
+ return NULL;
+ }
+}
+
+Document *document_load(AeFile *f) {
+ int lc;
+ Document *d = document_create();
+ Layer *l = NULL;
+
+ if (!aeff_read_header(f, "Aewan Document v1")) goto exception;
+ if (!aeff_read_int(f, "layer-count", &lc)) goto exception;
+ if (!aeff_read_string(f, "meta-info", &d->metainfo)) goto exception;
+
+
+ /* load each layer (there are <lc> layers to load) */
+ while (lc--) {
+ if ( ! (l = layer_load(f)) ) goto exception;
+ document_add_layer(d, l);
+ l = 0; /* forget about the layer, it now belongs to the document */
+ }
+
+ if (!aeff_read_footer(f, "Aewan Document v1")) goto exception;
+ return d; /* all went well */
+
+/* I think exception handling is a pretty legitimate use of goto,
+ * so don't complain */
+exception:
+ if (d) document_destroy(d);
+ if (l) layer_destroy(l);
+ return NULL;
+}
+
+Document *document_load_OLD(FILE *f) {
+ /* THIS FUNCTION LOADS THE OLD FORMAT. FOR BACKWARD COMPATIBILITY ONLY */
+ int i; int lc;
+ Document *d; Layer *l;
+ if ('D' != fgetc(f) || 'O' != fgetc(f)) return NULL;
+
+ fread(&lc, sizeof(int), 1, f);
+
+ d = document_create();
+ if ( !(d->metainfo = floadstr(f)) ) {
+ document_destroy(d);
+ return NULL;
+ }
+
+ for (i = 0; i < lc; i++) {
+ if ( !(l = layer_load_OLD(f)) ) {
+ document_destroy(d);
+ return NULL;
+ }
+
+ document_add_layer(d, l);
+ }
+
+ return d;
+}
+
+Cell document_calc_effective_cell(Document *doc, int x, int y) {
+ int i;
+ Layer *lyr;
+ Cell result;
+ result.ch = 0x20, result.attr = 0x70;
+
+ for (i = doc->layer_count - 1; i >= 0; i--) {
+ lyr = doc->layers[i];
+ if (x < 0 || x >= lyr->width || y < 0 || y >= lyr->width) continue;
+ if (!lyr->visible) continue;
+ if (lyr->transp && is_cell_transp(&lyr->cells[x][y])) continue;
+
+ result.ch = lyr->cells[x][y].ch;
+ result.attr = lyr->cells[x][y].attr;
+ }
+
+ return result;
+}
+
diff --git a/document.h b/document.h
new file mode 100644
index 0000000..5d4de51
--- /dev/null
+++ b/document.h
@@ -0,0 +1,108 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_document_h
+#define _btco_aewan_document_h
+#include "layer.h"
+#include "aeff.h"
+
+struct _Document {
+ int layer_count; /* how many layers in document */
+ Layer **layers; /* vector of pointers to layers */
+
+ char *metainfo; /* additional textual information. The program will
+ * invoke an external editor when the user wants
+ * to edit the contents of this string. */
+};
+typedef struct _Document Document;
+
+/* Creates a new, empty document. */
+Document *document_create(void);
+
+/* Destroys a previously created document */
+void document_destroy(Document *doc);
+
+/* Adds a new layer to the given document. After the call, the layer
+ * will belong to the document and no other references to it should
+ * be kept. */
+void document_add_layer(Document *doc, Layer *layer);
+
+/* Add a new layer to the given document, inserting it just before
+ * the layer whose index is i. Prerequsite: 0 <= i <= doc->layer_count.
+ * Notice that document_add_layer(doc, l) is equivalent to
+ * document_insert_layer(doc, doc->layer_count, l) */
+void document_insert_layer(Document *doc, int i, Layer *layer);
+
+/* Deletes layer i from the document. */
+void document_del_layer(Document *doc, int i);
+
+/* Convenience function that obtains the "nominal width and height"
+ * of the document, which are the dimensions of the first layer,
+ * if the document has any layers, or some sensible defaults if
+ * the document has none */
+void document_get_nom_dim(Document *doc, int *w, int *h);
+
+/* Saves document to file f */
+void document_save(Document *doc, AeFile *f);
+
+/* Loads a document from file f. If the loading succeeds, returns
+ * a dynamically allocated document. If the loading fails, returns NULL.
+ * This function reads the OLD, binary file format. */
+Document *document_load_OLD(FILE *f);
+
+/* Loads a document from file f. If the loading succeeds, returns
+ * a dynamically allocated document. If the loading fails, returns NULL.
+ * This function reads the NEW, zipped-text format.
+ *
+ * On error, this function returns NULL and aeff_get_error can be
+ * called in order to obtain an error description.
+ */
+Document *document_load(AeFile *f);
+
+/* A wrapper that opens the file, detects the format and calls
+ * either document_load or document_load_OLD.
+ *
+ * On error, this function returns NULL and aeff_get_error can
+ * be called in order to obtain an error description.
+ */
+Document *document_load_from(const char *filename);
+
+/* Gets the character and attribute at position x, y when viewing
+ * the image as a composite. That is, go through all layers and see
+ * which ones are transparent, visible, etc, and thus calculate the
+ * resulting char/attr of the given cell. */
+Cell document_calc_effective_cell(Document *doc, int x, int y);
+
+#endif
+
diff --git a/editmeta.c b/editmeta.c
new file mode 100644
index 0000000..e5f7b6d
--- /dev/null
+++ b/editmeta.c
@@ -0,0 +1,123 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ncurses.h>
+#include <unistd.h>
+
+#include "document.h"
+#include "psd.h"
+#include "ui.h"
+
+void edit_metainfo(void) {
+ char *editor;
+ FILE *f;
+ int fd, ret, size, i;
+ static char tmpname[64];
+ static char buf[128];
+ mode_t oldumask;
+
+ editor = getenv("VISUAL");
+ if (!editor) editor = getenv("EDITOR");
+ if (!editor) editor = "vi";
+
+ /* create a temporary file */
+ strcpy(tmpname, "/tmp/aewan-XXXXXX");
+ oldumask = umask(077); /* so that mkstemp creates a file with perms=700 */
+ fd = mkstemp(tmpname);
+ umask(oldumask);
+
+ /* check for error */
+ if (fd < 0) {
+ sprintf(buf, "ERROR creating temp file: %s", strerror(errno));
+ ui_message(buf, UIMSG_ERROR);
+ return;
+ }
+
+ /* do an fdopen so we can manipulate it via FILE* structure */
+ f = fdopen(fd, "w");
+
+ /* write current contents of metainfo string to the file */
+ if (_doc->metainfo) fputs(_doc->metainfo, f);
+
+ /* close file */
+ fclose(f);
+ close(fd); /* is this necessary? */
+
+ /* fire up editor */
+ sprintf(buf, "%s %s", editor, tmpname);
+ clear();
+ refresh();
+ endwin(); /* temporarily stop curses */
+ if ( (ret = system(buf)) ) {
+ /* error code returned */
+ sprintf(buf, "ERROR: editor (%s) returned error code %d.", editor, ret);
+ ui_message(buf, UIMSG_ERROR);
+ return;
+ }
+
+ /* restore curses */
+ touchwin(stdscr); /* force full redraw */
+ refresh();
+
+ /* ok, now read back file contents into metainfo string */
+ f = fopen(tmpname, "r");
+ if (!f) {
+ ui_message("ERROR: Failed to read back temp file.", UIMSG_ERROR);
+ return;
+ }
+
+ /* calculate file size */
+ fseek(f, 0, SEEK_END);
+ size = ftell(f) + 2; /* +1 b/c size is one more than last position.
+ We add another byte for the null terminator */
+ fseek(f, 0, SEEK_SET);
+
+ /* allocate appropriately */
+ dstrset(&_doc->metainfo, NULL);
+ _doc->metainfo = zalloc(size);
+
+ /* read file data */
+ i = fread(_doc->metainfo, 1, size, f);
+
+ /* put the null terminator where it should be */
+ _doc->metainfo[i] = 0;
+
+ /* delete temp file */
+ unlink(tmpname);
+}
+
diff --git a/editmeta.h b/editmeta.h
new file mode 100644
index 0000000..936a827
--- /dev/null
+++ b/editmeta.h
@@ -0,0 +1,41 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewan_editmeta_h
+#define _btco_aewan_editmeta_h
+
+/* Allows user to edit the document's meta-info in an editor */
+void edit_metainfo(void);
+
+#endif
+
diff --git a/export.c b/export.c
new file mode 100644
index 0000000..ba79d3d
--- /dev/null
+++ b/export.c
@@ -0,0 +1,86 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include <string.h>
+#include "export.h"
+
+void decode_cell(const Cell* cell, DecodedCell *dc) {
+ dc->fg = (cell->attr & 0xf0) >> 4;
+ dc->bg = cell->attr & 0x0f;
+ dc->ch = cell->ch;
+
+ dc->fg3 = (cell->attr & 0x70) >> 4;
+ dc->bg3 = cell->attr & 0x07;
+ dc->bold = (cell->attr & 0x80) ? 1 : 0;
+ dc->blink = (cell->attr & 0x08) ? 1 : 0;
+}
+
+bool export_vlayer_to_ansi(VirtualLayer *vl, bool use_ansi, bool use_newlines,
+ bool quotemeta, FILE *f) {
+ int x, y;
+ DecodedCell dec;
+ Cell c;
+ int cur_fg = -1;
+ int cur_bg = -1;
+ const char *must_quote = "\\`$";
+
+ for (y = 0; y < vl->height; y++) {
+ for (x = 0; x < vl->width; x++) {
+ vlayer_get_cell(vl, &c, x, y);
+ decode_cell(&c, &dec);
+
+ /* set up color if necessary */
+ if (use_ansi && (dec.fg != cur_fg || dec.bg != cur_bg)) {
+ fputs("\e[", f);
+ fputs(dec.bold ? "1;" : "0;", f);
+ if (dec.blink) fputs("5;", f);
+ fprintf(f, "%d;%dm", 30 + dec.fg3, 40 + dec.bg3);
+
+ cur_fg = dec.fg;
+ cur_bg = dec.bg;
+ }
+
+ /* output the character */
+ if (dec.ch >= 0 && dec.ch <= 32) dec.ch = ' ';
+
+ if (quotemeta && strchr(must_quote, dec.ch)) fputc('\\', f);
+ fputc(dec.ch, f);
+ }
+
+ if (use_newlines) fputc('\n', f);
+ }
+
+ if (use_ansi) fputs("\e[0m", f);
+ return true;
+}
+
diff --git a/export.h b/export.h
new file mode 100644
index 0000000..8774514
--- /dev/null
+++ b/export.h
@@ -0,0 +1,74 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_export_h
+#define _btco_aewan_export_h
+
+#include <stdio.h>
+#include <stdbool.h>
+#include "layer.h"
+#include "vlayer.h"
+
+/* Exports the given virtual layer to text format, writing the output to the
+ * given file. The parameter use_ansi_escape determines whether the function
+ * should include ANSI escape sequences to reproduce the colors.
+ * The use_newlines parameter indicates whether a newline character should
+ * be included after each row of output. The output will be written
+ * to the file f. The quotemeta parameter indicates that special UNIX
+ * characters such as backslashes and backticks should be escaped. */
+bool export_vlayer_to_ansi(VirtualLayer *vl, bool use_ansi_escape,
+ bool use_newlines,
+ bool quotemeta, FILE *f);
+
+/* Represents a decoded cell (see decode_cell()) below */
+typedef struct { /* represents a decoded document cell. Returned
+ * by decode_cell */
+
+ int fg, bg; /* the foreground and background color codes (4 bit, 0-15)
+ * for the cell */
+ int ch; /* the character in the cell */
+
+ /* now some of the same information, but in a more broken-down form: */
+ bool bold, blink; /* bold and blink attributes */
+ int fg3, bg3; /* 3-bit color codes (0-7) for the foreground and
+ * background of the cell */
+} DecodedCell;
+
+/* Decodes a cell into a 'decoded cell' structure that gives organized
+ * information about a cell, such as foreground and background colors
+ * and such. Returns the decoded cell information in *r_dc. */
+void decode_cell(const Cell *c, DecodedCell *r_dc);
+
+#endif
+
diff --git a/filedlg.c b/filedlg.c
new file mode 100644
index 0000000..d0b1ce3
--- /dev/null
+++ b/filedlg.c
@@ -0,0 +1,319 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+/*
+DIALOG LAYOUT (FULL SCREEN):
+
+ DIALOG TITLE
+ File Name: [filename_fld] [ cancel_btn ] [ ok_btn ]
+ Directory: [directory_lbl]
+ +--Directories---------+ +--Files-----------------+
+ | dirs_box | | files_box |
+ +----------------------+ +------------------------+
+*/
+
+#include <ncurses.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "bores/bores.h"
+#include "aewl/aewl.h"
+#include "aewl/allwidgets.h"
+#include "keys.h"
+
+/* widget positions (w, h and screen dimensions) */
+/* btw, STLBL = static label, that is, labels that
+ * are just there to say things that never change
+ * (didn't that come out somewhat poetic?) */
+#define FILENAME_STLBL_X 1
+#define FILENAME_STLBL_Y 2
+#define DIRECTORY_STLBL_X 1
+#define DIRECTORY_STLBL_Y 3
+#define CANCEL_BTN_W 11
+#define OK_BTN_W 11
+#define CANCEL_BTN_X (w - CANCEL_BTN_W - OK_BTN_W - 2)
+#define CANCEL_BTN_Y 2
+#define OK_BTN_X (w - OK_BTN_W)
+#define OK_BTN_Y 2
+#define FILENAME_FLD_X 13
+#define FILENAME_FLD_Y 2
+#define FILENAME_FLD_W (CANCEL_BTN_X - FILENAME_FLD_X - 3)
+#define DIRECTORY_LBL_X 13
+#define DIRECTORY_LBL_Y 3
+#define DIRECTORY_LBL_W (w - DIRECTORY_LBL_X)
+#define DIRS_BOX_X 1
+#define DIRS_BOX_Y 5
+#define DIRS_BOX_W (w / 3)
+#define DIRS_BOX_H (h - 6)
+#define FILES_BOX_X (DIRS_BOX_X + DIRS_BOX_W + 2)
+#define FILES_BOX_Y 5
+#define FILES_BOX_W (w - FILES_BOX_X - 1)
+#define FILES_BOX_H (h - 6)
+
+/* result codes for internal event handling */
+#define FILENAME_FLD_RES 1001
+#define FILES_BOX_RES 1002
+#define DIRS_BOX_RES 1003
+#define CANCEL_BTN_RES 1004
+#define OK_BTN_RES 1005
+
+static AewlWidget *filename_fld, *cancel_btn, *ok_btn,
+ *directory_lbl, *dirs_box, *files_box,
+ *filename_stlbl, *directory_stlbl;
+static AewlForm *form;
+
+static char *curdir = NULL; /* the currently selected directory (full path).
+ * This will persist across invocations of the dialog. */
+
+/* fills the dirs listbox with the subdirectories of the current directory,
+ * updates the file listbox with the files in the current directory and
+ * all such things */
+static void _update_widgets(void);
+
+static bool _is_dir_valid(const char *dir) {
+ DIR *d = opendir(dir);
+ if (d) {
+ closedir(d);
+ return true;
+ }
+
+ return false;
+}
+
+static char *my_getcwd() { /* returns newly allocated buffer. NULL on error */
+ int cap;
+ char *s = malloc(cap = 32);
+
+ while (!getcwd(s, cap)) {
+ if (errno != ERANGE) return NULL;
+ s = malloc(cap += cap);
+ }
+
+ return s;
+}
+
+static char *_get_canon_dir_path(const char *base, const char *relative) {
+ /* Warning: this is a ridiculous way to go about this */
+ char *oldpwd = my_getcwd();
+ char *retval;
+
+ if (!oldpwd) return NULL;
+
+ if (0 != chdir(base)) return NULL;
+ if (0 != chdir(relative)) return NULL;
+
+ retval = my_getcwd();
+
+ if (0 != chdir(oldpwd)) {
+ fprintf(stderr, "PANIC: Can't go back to old wd '%s'\n%s\n",
+ oldpwd, strerror(errno));
+ abort();
+ }
+
+ return retval;
+}
+
+char *filedlg_show(const char *title) {
+ int w, h, r, ch, s;
+ char *retval = NULL;
+
+ /* if the current directory is unset or is invalid (for example
+ * has been deleted since the file dialog was last invoked),
+ * reset it to the application's current working directory */
+ if (!curdir || !_is_dir_valid(curdir)) {
+ curdir = my_getcwd();
+ if (!curdir) curdir = strdup("/"); /* last resort -- this will
+ * happen if the current working
+ * directory of the application is
+ * removed, for example. */
+ }
+
+ push_screen();
+ clear();
+
+ kurses_color(14, 0);
+ kurses_move(0, 0);
+ addstr(title);
+
+ w = kurses_width();
+ h = kurses_height();
+
+ form = aewl_form_create(stdscr);
+ filename_stlbl = aewl_label_create(FILENAME_STLBL_X, FILENAME_STLBL_Y, 0,
+ "File &Name:");
+ directory_stlbl = aewl_label_create(DIRECTORY_STLBL_X, DIRECTORY_STLBL_Y, 0,
+ "Directory:");
+ filename_fld = aewl_field_create(FILENAME_FLD_X, FILENAME_FLD_Y,
+ FILENAME_FLD_W, KEY_ALT_N, FILENAME_FLD_RES, "");
+ directory_lbl = aewl_label_create(DIRECTORY_LBL_X, DIRECTORY_LBL_Y,
+ DIRECTORY_LBL_W, "");
+ cancel_btn = aewl_button_create(CANCEL_BTN_X, CANCEL_BTN_Y, CANCEL_BTN_W,
+ 0, CANCEL_BTN_RES, "Cancel");
+ ok_btn = aewl_button_create(OK_BTN_X, OK_BTN_Y, OK_BTN_W,
+ 0, OK_BTN_RES, "OK");
+ files_box = aewl_listbox_create(FILES_BOX_X, FILES_BOX_Y,
+ FILES_BOX_W, FILES_BOX_H,
+ KEY_ALT_F, "&Files", FILES_BOX_RES);
+ dirs_box = aewl_listbox_create(DIRS_BOX_X, DIRS_BOX_Y,
+ DIRS_BOX_W, DIRS_BOX_H,
+ KEY_ALT_D, "&Directory", DIRS_BOX_RES);
+
+ /* set widget focus peers */
+ aewl_label_set_focus_peer((AewlLabel*) filename_stlbl, filename_fld);
+
+ /* add all widgets to the form */
+ aewl_form_add_widget(form, filename_stlbl);
+ aewl_form_add_widget(form, directory_stlbl);
+ aewl_form_add_widget(form, filename_fld);
+ aewl_form_add_widget(form, directory_lbl);
+ aewl_form_add_widget(form, cancel_btn);
+ aewl_form_add_widget(form, ok_btn);
+ aewl_form_add_widget(form, dirs_box);
+ aewl_form_add_widget(form, files_box);
+
+ /* show the form */
+ _update_widgets();
+ aewl_form_paint(form, true);
+ while (1) {
+ /* if files box has focus, set the field's text to match current
+ * selection */
+ if (aewl_form_get_focus_widget(form) == files_box) {
+ const char *s = aewl_listbox_get((AewlListBox*) files_box,
+ aewl_listbox_get_sel((AewlListBox*) files_box));
+ if (s) aewl_field_set_text((AewlField*) filename_fld, s);
+ aewl_form_paint(form, true);
+ }
+
+ /* get next key and dispatch it */
+ ch = getch();
+ r = aewl_form_dispatch_key(form, ch);
+
+ /* interpret returned result code */
+ if (r == CANCEL_BTN_RES || ch == 27 || ch == 3 || ch == 7) {
+ /* if user pressed the cancel button, pressed ESC or Ctrl+C or Ctrl+G,
+ * cancel dialog */
+ retval = NULL;
+ break;
+ }
+ else if (r == FILENAME_FLD_RES || r == OK_BTN_RES || r == FILES_BOX_RES) {
+ /* if user confirmed selection, quit dialog and return the
+ * currently selected file, that is, the current directory
+ * plus the field's contents (remember that it will already have
+ * been updated to match the filebox's selection, if appropriate) */
+ const char *fieldtext = aewl_field_get_text((AewlField*)filename_fld);
+
+ /* TODO: work needs to be done here to enable the user to,
+ * for example, type a full path to save the file, or
+ * type the name of a directory to jump to it. At the very
+ * least, this should disallow slashes in the file name! */
+
+ retval = malloc(strlen(fieldtext) + strlen(curdir) + 6);
+ sprintf(retval, "%s/%s", curdir, fieldtext);
+ break;
+ }
+ else if (r == DIRS_BOX_RES &&
+ (s = aewl_listbox_get_sel((AewlListBox*) dirs_box)) >= 0) {
+ /* user pressed enter in the directories box, so change into that
+ * directory */
+ const char *d = aewl_listbox_get((AewlListBox*) dirs_box, s);
+
+ /* get the canonicalized name of the new directory */
+ char *canon_path = _get_canon_dir_path(curdir, d);
+
+ if (!canon_path) return NULL; /* FIXME: error message? */
+
+ if (_is_dir_valid(canon_path)) {
+ if (curdir) free(curdir);
+ curdir = canon_path;
+
+ /* clear file name text field */
+ aewl_field_set_text((AewlField*) filename_fld, "");
+
+ _update_widgets();
+ aewl_form_paint(form, true);
+ }
+ else
+ free(canon_path);
+ /* FIXME: Should't we display a message if the directory is invalid? */
+ }
+ }
+
+ aewl_form_destroy(form);
+ pop_screen();
+
+ return retval; /* return filename if user pressed ok */
+}
+
+static void _update_widgets(void) {
+ DIR *d;
+ struct dirent *dent;
+ struct stat st;
+
+ d = opendir(curdir);
+
+ if (!d) {
+ fprintf(stderr, "ERROR in opendir(\"%s\"): %s\n", curdir,
+ strerror(errno));
+ abort();
+ }
+
+ aewl_listbox_clear((AewlListBox*) dirs_box);
+ aewl_listbox_clear((AewlListBox*) files_box);
+ while ( (dent = readdir(d)) ) {
+ char *compname = zalloc(strlen(dent->d_name) + strlen(curdir) + 2);
+ sprintf(compname, "%s/%s", curdir, dent->d_name);
+
+ if (0 != stat(compname, &st)) continue; /* broken links and such */
+
+ free(compname);
+
+ if (S_ISDIR(st.st_mode))
+ aewl_listbox_add((AewlListBox*) dirs_box, dent->d_name);
+ else
+ aewl_listbox_add((AewlListBox*) files_box, dent->d_name);
+ }
+ aewl_listbox_sort((AewlListBox*) dirs_box);
+ aewl_listbox_sort((AewlListBox*) files_box);
+
+ closedir(d);
+
+ /* update the directory label */
+ aewl_label_set_text((AewlLabel*)directory_lbl, curdir);
+}
+
diff --git a/filedlg.h b/filedlg.h
new file mode 100644
index 0000000..74d25ac
--- /dev/null
+++ b/filedlg.h
@@ -0,0 +1,49 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewan_filedlg_h
+#define _btco_aewan_filedlg_h
+
+/* Shows a file dialog onscreen and returns the filename
+ * that the user selected. Caller is responsibile for
+ * freeing the returned buffer.
+ *
+ * title is the title that will be shown across the
+ * top of the screen
+ *
+ * Returns NULL if the user cancels the dialog
+ */
+char *filedlg_show(const char *title);
+
+#endif
+
diff --git a/handlekey.c b/handlekey.c
new file mode 100644
index 0000000..0d900a3
--- /dev/null
+++ b/handlekey.c
@@ -0,0 +1,624 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#include <stdbool.h>
+#include "bores/bores.h"
+#include <limits.h>
+#include <stdlib.h>
+#include <ncurses.h>
+#include <string.h>
+#include <errno.h>
+#include <pwd.h> /* For getpwuid() */
+#include <unistd.h>
+
+#include "handlekey.h"
+#include "document.h"
+#include "psd.h"
+#include "ui.h"
+#include "keys.h"
+#include "clipboard.h"
+#include "colordlg.h"
+#include "layerdlg.h"
+#include "helpdlg.h"
+#include "chtr.h"
+#include "editmeta.h"
+#include "keybind.h"
+#include "commands.h"
+#include "menubar.h"
+#include "welcomedlg.h"
+#include "filedlg.h"
+
+#define FAST_MOVE_AMOUNT 8 /* how much the cursor moves each time the fast
+ * movent keys (Ctrl+Z, Ctrl+X) are pressed */
+
+/* Interacts with the user in order to allow him to add a new layer to the
+ * document. If <interactive>, asks user for parameters; else just
+ * adds using the defaults. */
+static void u_add_layer(bool interactive) {
+ int width, height; int nom_width, nom_height;
+ char *name; Layer *lyr;
+
+ document_get_nom_dim(_doc, &nom_width, &nom_height);
+ if (interactive) {
+ width = ui_ask_i("NEW LAYER: Enter width",
+ nom_width, 2, INT_MAX); if (ui_cancel) return;
+ height = ui_ask_i("NEW LAYER: Enter height",
+ nom_height, 2, INT_MAX); if (ui_cancel) return;
+ name = ui_ask_s("NEW LAYER: Name", "unnamed"); if (ui_cancel) return;
+ }
+ else {
+ width = nom_width;
+ height = nom_height;
+ name = strdup("unnamed");
+ }
+
+ lyr = layer_create(name, width, height);
+
+ /* if this is the first layer we are adding, make it opaque;
+ * otherwise make it transparent */
+ if (_doc->layer_count) lyr->transp = true;
+ else lyr->transp = false;
+
+ document_insert_layer(_doc, 0, lyr);
+
+ free(name);
+}
+
+/* Interacts with the user in order to allow him to rename the current
+ * layer */
+static void u_rename_layer(void) {
+ Layer *l = _doc->layers[_lyr];
+ char *new_name;
+
+ new_name = ui_ask_s("Rename layer to", l->name);
+ if (!ui_cancel)
+ dstrset(&l->name, new_name);
+
+ if (new_name) free(new_name);
+}
+
+/* Interacts with the user in order to allow him to resize the current
+ * layer */
+static void u_resize_layer(void) {
+ Layer *l = _doc->layers[_lyr];
+ Layer *new_l;
+ int h, w, x, y;
+
+ w = ui_ask_i("RESIZE LAYER: Enter new width",
+ l->width, 2, INT_MAX); if (ui_cancel) return;
+ h = ui_ask_i("RESIZE LAYER: Enter new height",
+ l->height, 2, INT_MAX); if (ui_cancel) return;
+
+ new_l = layer_create(l->name, w, h);
+
+ w = l->width > new_l->width ? new_l->width : l->width;
+ h = l->height > new_l->height ? new_l->height : l->height;
+
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++) {
+ new_l->cells[x][y].ch = l->cells[x][y].ch;
+ new_l->cells[x][y].attr = l->cells[x][y].attr;
+ }
+
+ layer_destroy(l);
+ _doc->layers[_lyr] = new_l;
+}
+
+/* Duplicates current layer, adding a duplicate to the end of the
+ * layer stack. */
+static void u_dup_layer(void) {
+ char buf[32];
+ Layer *l;
+ sprintf(buf, "copy of %d", _lyr);
+
+ l = _doc->layers[_lyr];
+ document_add_layer(_doc, layer_dup(buf, l));
+ switch_to_layer(_doc->layer_count - 1);
+}
+
+/* Return home directory of specified user name.
+ * If name is omitted, returns current user's home dir. */
+char *get_home_dir(char *name) {
+ char msg[128];
+ char *home_dir;
+ struct passwd *pw;
+
+ if(name) {
+ pw = getpwnam(name);
+ if(!pw)
+ goto doesnt_have;
+ return pw->pw_dir;
+ } else {
+ home_dir = getenv("HOME");
+ if(home_dir) {
+ return home_dir;
+ } else {
+ /* $HOME isn't set. Get directory from /etc/passwd. */
+ pw = getpwuid(getuid());
+ if(!pw)
+ goto doesnt_have;
+ return pw->pw_dir;
+ }
+ }
+
+ /* Only reached with goto. */
+doesnt_have:
+ sprintf(msg, "ERROR: User '%s' doesn't have a home directory.", name);
+ ui_message(msg, UIMSG_ERROR);
+ return NULL;
+}
+
+/* Returns filename with '~' replaced with the user's
+ * home directory. */
+static char *expand_tilde(char *filename) {
+ char *home_dir;
+ char *slash;
+
+ if(filename[1]) {
+ char *username, *filename_dup;
+ char *ret;
+
+ filename_dup = strdup(filename);
+ slash = strchr(filename_dup, '/');
+ username = filename_dup + 1;
+
+ if(!slash) {
+ /* Only "~user" was given, use it as a filename. */
+ free(filename_dup);
+ return filename;
+ }
+
+ *slash = '\0';
+
+ if(!strlen(username))
+ username = NULL;
+ home_dir = get_home_dir(username);
+ if(!home_dir)
+ return NULL;
+
+ slash++; /* Everything after the tilde and possible username. */
+ ret = malloc(strlen(home_dir) + strlen(slash) + 1);
+ sprintf(ret, "%s/%s", home_dir, slash);
+ free(filename_dup);
+ return ret;
+ } else {
+ /* Only a tilde was given, use it as a filename. */
+ return filename;
+ }
+}
+
+/* Interacts with the user in order to allow him to load a different
+ * file into the editor. If the <filename> argument is not NULL,
+ * this routine will not ask the user for the filename but will
+ * rather use the supplied filename as the file to load. */
+void u_load_file(const char *supplied_filename) {
+ char *filename;
+ FILE *f = NULL;
+ char msg[128];
+ Document *newdoc;
+
+ if (!supplied_filename) {
+ filename = filedlg_show("Load File");
+ if (!filename) return;
+ }
+ else filename = strdup(supplied_filename);
+
+ if ( !(newdoc = document_load_from(filename)) ) {
+ sprintf(msg, "ERROR: Failed to load file. -- More --");
+ ui_message(msg, UIMSG_ERROR);
+ ui_message(aeff_get_error(), UIMSG_ERROR);
+ goto cleanup;
+ }
+
+ /* now that we have the new document, do the actual replacement */
+ document_destroy(_doc);
+ _doc = newdoc;
+
+ /* set the filename of the loaded file */
+ dstrset(&_filename, filename);
+
+cleanup:
+ if (f) fclose(f);
+ if (filename) free(filename);
+}
+
+/* Interacts with the user allowing him to save current file */
+static void u_save_file(bool forceAsk) {
+ char *filename, *expanded_filename;
+ FILE *tmpf;
+ AeFile *f = 0;
+ char msg[128];
+
+ if (forceAsk || !_filename || !strlen(_filename)) {
+ filename = filedlg_show("Save File As");
+ if (!filename) return;
+ }
+ else filename = strdup(_filename);
+
+ if (filename[0] == '~') {
+ expanded_filename = expand_tilde(filename);
+ if (!expanded_filename) return;
+
+ /* Comparing pointers. */
+ if (expanded_filename != filename) {
+ free(filename);
+ filename = expanded_filename;
+ }
+ }
+
+ if ( _filename && strcmp(_filename, filename) &&
+ (tmpf = fopen(filename, "r")) ) {
+ /* file exists. Ask if user wants to overwrite */
+ fclose(tmpf); tmpf = 0;
+ if (!ui_ask_yn("FILE EXISTS. Overwrite?", 0) || ui_cancel) {
+ ui_message("File was NOT saved!", UIMSG_INFORM);
+ goto cleanup;
+ }
+ }
+
+ if ( !(f = aeff_open(filename, 'w')) ) {
+ sprintf(msg, "ERROR: Can't write to file. %s.", aeff_get_error());
+ ui_message(msg, UIMSG_ERROR);
+ goto cleanup;
+ }
+
+ document_save(_doc, f);
+
+ dstrset(&_filename, filename);
+
+ sprintf(msg, "File saved: %s.", filename);
+ ui_message(msg, UIMSG_INFORM);
+
+cleanup:
+ if (f) aeff_close(f);
+ if (filename) free(filename);
+}
+
+/* erases current selection */
+static void erase_sel() {
+ int x, y;
+ int x0, x1, y0, y1;
+
+ get_norm_sel(&x0, &y0, &x1, &y1);
+ for (x = x0; x <= x1; x++)
+ for (y = y0; y <= y1; y++)
+ _doc->layers[_lyr]->cells[x][y] = BLANK_CELL;
+}
+
+/* if <fg>, sets foreground color of selection to current foreground
+ * color. Else, sets background color of selection to current background. */
+static void tint_sel(bool fg) {
+ int x0, y0, x1, y1, x, y;
+ get_norm_sel(&x0, &y0, &x1, &y1);
+
+ for (x = x0; x <= x1; x++)
+ for (y = y0; y <= y1; y++)
+ if (fg)
+ _doc->layers[_lyr]->cells[x][y].attr =
+ (_fg << 4) | (_doc->layers[_lyr]->cells[x][y].attr & 0x0F);
+ else
+ _doc->layers[_lyr]->cells[x][y].attr =
+ _bg | (_doc->layers[_lyr]->cells[x][y].attr & 0xF0);
+}
+
+/* Remaps character ch to its lgmode equivalent. When in _lgmode == true,
+ * this function is executed for every character typed. */
+static int lgmode_map_ch(int ch) {
+ switch (ch) {
+ case '7': return AEWAN_CHAR_ULCORNER;
+ case '8': return AEWAN_CHAR_TTEE;
+ case '9': return AEWAN_CHAR_URCORNER;
+ case '4': return AEWAN_CHAR_LTEE;
+ case '5': return AEWAN_CHAR_PLUS;
+ case '6': return AEWAN_CHAR_RTEE;
+ case '1': return AEWAN_CHAR_LLCORNER;
+ case '2': return AEWAN_CHAR_BTEE;
+ case '3': return AEWAN_CHAR_LRCORNER;
+ case '-': return AEWAN_CHAR_HLINE;
+ case '|': return AEWAN_CHAR_VLINE;
+ case '0': return AEWAN_CHAR_CKBOARD;
+ default : return ch;
+ }
+}
+
+/* handle special keys for SM_SELECT mode */
+static void sm_select_handle_key(int ch) {
+ int x0, y0, x1, y1;
+ int tmp;
+ get_norm_sel(&x0, &y0, &x1, &y1);
+
+ /* we are in SM_SELECT mode */
+ switch (ch) {
+ case 'm':
+ _selmode = SM_FLOAT;
+ copy_sel_to_clipboard();
+ erase_sel();
+ _x = x0; _y = y0;
+ break;
+ case 'c':
+ _selmode = SM_FLOAT;
+ copy_sel_to_clipboard();
+ _x = x0; _y = y0;
+ break;
+ case 'e':
+ _selmode = SM_NONE;
+ erase_sel();
+ break;
+ case 'f':
+ tint_sel(true);
+ break;
+ case 'b':
+ tint_sel(false);
+ break;
+ case 'o':
+ /* swap the anchor with the cursor position *
+ * that will enable the user to manipulate the "other edge"
+ * of the rectangle */
+ tmp = _x; _x = _ax; _ax = tmp;
+ tmp = _y; _y = _ay; _ay = tmp;
+ break;
+ }
+}
+
+/* handle special keys for SM_FLOAT mode */
+static void sm_float_handle_key(int ch) {
+ switch (ch) {
+ case 's': /* stamp */
+ paste_clipboard();
+ break;
+ case 'x': case 'X': /* flip x */
+ layer_flip_x(_clipboard, ch == 'x');
+ break;
+ case 'y': case 'Y': /* flip y */
+ layer_flip_y(_clipboard, ch == 'y');
+ break;
+ case 't': case 'T': /* toggle transparency */
+ _clipboard->transp = !_clipboard->transp;
+ break;
+ }
+}
+
+/* Warns the user that he will be taken into an editor to edit the
+ * document's meta-info, then fires up the editor */
+void u_edit_meta(void) {
+ int x0, y0, x, y, ch;
+ kurses_color(7, 0);
+ draw_centered_window(40, 5, "Edit Metainfo", &x0, &y0);
+
+ x = x0, y = y0;
+ kurses_move(x, y++);
+ addstr("You will now be taken into an editor");
+ kurses_move(x, y++);
+ addstr("in which you will be able to edit this");
+ kurses_move(x, y++);
+ addstr("document's metainfo (arbitrary text).");
+
+ ch = getch();
+ if (ch == 7 || ch == 27) return;
+
+ edit_metainfo();
+}
+
+static void correct_coords(void) {
+ Layer *lyr;
+ int scr_width = kurses_width();
+ int scr_height = kurses_height();
+
+ if (!_doc->layer_count) return;
+ lyr = _doc->layers[_lyr];
+
+ /* clamp coordinates to bounds */
+ if (_x < 0) _x = 0;
+ if (_x >= lyr->width) _x = lyr->width - 1;
+ if (_y < 0) _y = 0;
+ if (_y >= lyr->height) _y = lyr->height - 1;
+
+ /* now correct scrolling */
+ if (_x >= _svx + scr_width) _svx = _x - scr_width + 1;
+ else if (_x < _svx) _svx = _x;
+ if (_y >= _svy + scr_height - 1) _svy = _y - scr_height + 2;
+ else if (_y < _svy) _svy = _y;
+}
+
+
+void handle_key(int ch) {
+ int command;
+ Layer *lyr;
+
+ /* ENABLE THIS TO DEBUG AEWL... */
+ #if 0
+ if (ch == KEY_F(10)) {
+ debug_aewl();
+ return;
+ }
+ #endif
+
+ /* first check for function keys (they open the menu) */
+ if (ch > KEY_F0 && ch <= KEY_F(12)) {
+ /* show menu and perform command mandated by it */
+ command = menubar_show(ch - KEY_F0 - 1);
+ if (command != COMMAND_UNDEFINED) handle_command(command);
+ return;
+ }
+
+ if ( (command = keybind_translate(ch)) ) {
+ /* key triggers a command: execute command */
+ handle_command(command);
+ if (ch != 27) return; /* we also want to handle 27 (escape) ourselves
+ * below */
+ }
+
+ /* key does not trigger a command; handle it normally if there are
+ * layers in the document; ignore it if there aren't */
+ if (!_doc->layer_count) return;
+ lyr = _doc->layers[_lyr];
+
+ /* interpret character keys for no-selection mode */
+ if (printable_char(ch) && _selmode == SM_NONE) {
+ int ch_to_put = _lgmode ? lgmode_map_ch(ch) : ch;
+
+ if (_insmode) {
+ int x;
+ for (x = lyr->width - 1; x > _x; x--)
+ lyr->cells[x][_y] = lyr->cells[x-1][_y];
+ }
+
+ lyr->cells[_x][_y].ch = ch_to_put;
+ lyr->cells[_x][_y].attr = _fg << 4 | _bg;
+ _x++;
+ }
+
+ /* interpret character keys for SM_SELECT and SM_FLOAT modes */
+ if (_selmode == SM_SELECT) sm_select_handle_key(ch);
+ else if (_selmode == SM_FLOAT) sm_float_handle_key(ch);
+
+ /* interpret the backspace and delete keys, also for no-sel mode */
+ if (_selmode == SM_NONE &&
+ ((_x > 0 && (ch == 8 || ch == KEY_BACKSPACE || ch == 127))
+ || ch == KEY_DC)) {
+ int x;
+ _selmode = false;
+ if (ch != KEY_DC) _x--; /* we know this can't make _x negative, the
+ * condition on the "if" above guarantees that */
+ for (x = _x; x < lyr->width - 1; x++)
+ lyr->cells[x][_y] = lyr->cells[x+1][_y];
+
+ lyr->cells[lyr->width - 1][_y] = BLANK_CELL;
+ }
+
+ correct_coords();
+};
+
+void handle_command(int command) {
+ int newfg, newbg;
+ int ret;
+ Layer *lyr;
+
+ /* handle commands that work regardless of whether document is empty */
+ switch (command) {
+ case COMMAND_QUIT:
+ ret = ui_ask_yn("Really quit aewan?", 0);
+ if (!ui_cancel && ret) exit(0);
+ break;
+ case COMMAND_ADD_LAYER_DEFAULTS:
+ case COMMAND_ADD_LAYER_SPECIFY:
+ u_add_layer(command == COMMAND_ADD_LAYER_SPECIFY);
+ if (!doc_empty()) _lyr = 0; /* now we have a layer, so correct _lyr
+ * so that it makes sense */
+ return;
+ case COMMAND_SET_FOREGROUND:
+ newfg = ui_ask_color("Foreground color");
+ if (!ui_cancel) _fg = newfg;
+ return;
+ case COMMAND_SET_BACKGROUND:
+ newbg = ui_ask_color("Background color");
+ if (!ui_cancel) _bg = newbg;
+ return;
+ case COMMAND_SHOW_COLOR_DLG: show_color_dlg(); return;
+ case COMMAND_TOGGLE_INSERT: _insmode = !_insmode; return;
+ case COMMAND_SHOW_HELP_DLG: show_help_dlg(); return;
+ case COMMAND_SHOW_ABOUT_DLG: show_welcome_dlg(); return;
+ case COMMAND_LOAD_FILE: u_load_file(NULL); return;
+ case COMMAND_SAVE_FILE: u_save_file(false); return;
+ case COMMAND_SAVE_FILE_AS: u_save_file(true); return;
+ case COMMAND_NEW_FILE:
+ if (_doc->layer_count > 0) {
+ ret = ui_ask_yn("Really start a new document?", 0);
+ if (ui_cancel || !ret) break;
+ }
+ document_destroy(_doc);
+ zero_state();
+ return;
+ case COMMAND_EDIT_META: u_edit_meta(); return;
+ }
+
+ /* from this point on, we handle the keys that only work if the document
+ * is not empty */
+ if (doc_empty()) return;
+ lyr = _doc->layers[_lyr];
+
+ /* if clipboard exists and we are not in SM_FLOAT mode, delete it */
+ if (_clipboard && _selmode != SM_FLOAT) clear_clipboard();
+
+ switch (command) {
+ case COMMAND_MOVE_LEFT: _x--; break;
+ case COMMAND_MOVE_RIGHT: _x++; break;
+ case COMMAND_MOVE_UP: _y--; break;
+ case COMMAND_MOVE_DOWN: _y++; break;
+ case COMMAND_CARRIAGE_RETURN: _y++; _x = 0; break;
+ case COMMAND_PAGE_DOWN: _y += kurses_height() - 1; break;
+ case COMMAND_PAGE_UP: _y -= kurses_height() - 2; break;
+ case COMMAND_START_OF_LINE: _x = 0; break;
+ case COMMAND_END_OF_LINE: _x = lyr->width - 1; break;
+ case COMMAND_FAST_RIGHT: _x += FAST_MOVE_AMOUNT; break;
+ case COMMAND_FAST_LEFT: _x -= FAST_MOVE_AMOUNT; break;
+ case COMMAND_PICK_COLOR: /* pick up color from current position */
+ if (_selmode != SM_NONE) break;
+ _fg = lyr->cells[_x][_y].attr >> 4;
+ _bg = lyr->cells[_x][_y].attr & 0x0F;
+ break;
+ case COMMAND_TINT_CELL: /* tint cell under cursor with current color */
+ if (_selmode != SM_NONE) break;
+ lyr->cells[_x][_y].attr = _fg << 4 | _bg;
+ _x++;
+ break;
+
+ case COMMAND_TOGGLE_SELECTION: /* start or stop selection mode */
+ if (_selmode == SM_NONE) {
+ _selmode = SM_SELECT;
+ _ax = _x;
+ _ay = _y;
+ }
+ else _selmode = SM_NONE;
+ break;
+
+ case COMMAND_CANCEL: _selmode = SM_NONE; break;
+ case COMMAND_SHOW_LAYER_DLG:
+ show_layer_dlg(); /* bring up layer manager dialog */
+ /* make sure current layer is still valid */
+ if (_lyr > _doc->layer_count) _lyr = _doc->layer_count - 1;
+ break;
+ case COMMAND_NEXT_LAYER: switch_to_layer(_lyr+1); break;
+ case COMMAND_PREV_LAYER: switch_to_layer(_lyr-1); break;
+ case COMMAND_DUP_LAYER: u_dup_layer(); break;
+ case COMMAND_RENAME_LAYER: u_rename_layer(); break;
+ case COMMAND_RESIZE_LAYER: u_resize_layer(); break;
+
+ case COMMAND_TOGGLE_LINE_MODE: _lgmode = !_lgmode; break;
+ case COMMAND_TOGGLE_COMPOSITE: _compmode = !_compmode; break;
+ }
+
+ correct_coords();
+}
+
diff --git a/handlekey.h b/handlekey.h
new file mode 100644
index 0000000..3379f54
--- /dev/null
+++ b/handlekey.h
@@ -0,0 +1,50 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewan_handlekey_h
+#define _btco_aewan_handlekey_h
+
+/* Reacts to keypress. <ch> is the code of the key that was pressed */
+void handle_key(int ch);
+
+/* Reacts to the command <cmd>. Called from handle_key. */
+void handle_command(int cmd);
+
+/* Interacts with the user in order to allow him to load a file into
+ * the editor. If the supplied_filename parameter is not NULL, the
+ * user will not be asked for the filename; rather, the supplied
+ * filename will identify the file to be loaded */
+void u_load_file(const char *supplied_filename);
+
+#endif
+
diff --git a/helpdlg.c b/helpdlg.c
new file mode 100644
index 0000000..3d8fbb5
--- /dev/null
+++ b/helpdlg.c
@@ -0,0 +1,127 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+#include <ncurses.h>
+
+#include "helpdlg.h"
+
+static char *helptext[2] = {
+/* 345678901234567890123456789012345 */
+"\001Legend\002\n"
+"^ means the Ctrl key and % means\n"
+"the Alt key. Thus, ^A means \n"
+"Ctrl+A and %A means Alt-A.\n"
+"\n"
+"\001General keys\002\n"
+"^X,^Z fast horizontal movement\n"
+"^O open a file\n"
+"^S save file\n"
+"\n"
+"\001Layers\002\n"
+"^W go to next layer\n"
+"^Q go to previous layer\n"
+"^L bring up Layer Manager\n"
+"^A add layer (defaults)\n"
+"%A add layer (specify)\n"
+"^D add copy of current layer\n"
+"^R rename this layer\n"
+"%R resize this layer\n"
+"\n"
+"\001Selection\002\n"
+"%S enter select mode.\n"
+,
+"\001Colors\002\n"
+"TAB bring up color dialog\n"
+"%P pick color from cell\n"
+" under the cursor\n"
+"%Z apply color to cell\n"
+" under the cursor\n"
+"\n"
+"\001Mode toggles\002\n"
+"INS toggle insert mode\n"
+"^G toggle line-drawing mode\n"
+" (0-9,|,- will draw lines)\n"
+"^P toggle composite view\n"
+"\n"
+"\001Others\002\n"
+"^E edit document metainfo\n"
+"^C quit program\n"
+"F1-Fn show menu\n"
+"\n*************************************\n" /* will become ACS_HLINE */
+"Copyright (c) 2003 by\n"
+"Bruno T. C. de Oliveira\n"
+"All rights reserved."
+};
+
+void show_help_dlg(void) {
+ int x0, y0; int x, y; int i;
+ const char *p;
+
+ clear();
+ refresh();
+ kurses_color(4, 0);
+ addstr("Keys Quick Reference\n\n");
+ kurses_color(7, 0);
+
+ x0 = 0;
+ y0 = 2;
+
+ x = x0;
+ y = y0;
+ for (i = 0; i < 2; i++) {
+ x = x0 + i * 40;
+ y = y0;
+ p = helptext[i];
+
+ while (*p) {
+ kurses_move(x, y);
+ switch (*p) {
+ case 1: kurses_color(4, 0); break;
+ case 2: kurses_color(7, 0); break;
+ case '\n': x = x0 + i * 40; y++; break;
+ case '*': addch(ACS_HLINE); x++; break;
+ default: addch(*p); x++;
+ }
+
+ p++;
+ }
+ }
+
+ /* draw vertical line separating the two columns */
+ draw_vline(x0 + 37, y0, 24 - y0, ACS_VLINE, ACS_VLINE, ACS_VLINE);
+
+ refresh();
+ getch();
+}
+
diff --git a/helpdlg.h b/helpdlg.h
new file mode 100644
index 0000000..ef7bc59
--- /dev/null
+++ b/helpdlg.h
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_helpdlg_h
+#define _btco_aewan_helprdlg_h
+
+/* invokes the "help" dialog */
+void show_help_dlg(void);
+
+#endif
+
diff --git a/init_aewl.c b/init_aewl.c
new file mode 100644
index 0000000..76db64d
--- /dev/null
+++ b/init_aewl.c
@@ -0,0 +1,79 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "aewl/aewl.h"
+#include <ncurses.h>
+#include <stdbool.h>
+
+static int curses_attr_for_pair(int fg, int bg, bool bold) {
+ short int cp = bg * 8 + 7 - fg;
+ if (!cp) return bold ? A_BOLD : A_NORMAL;
+ return COLOR_PAIR(cp) | (bold ? A_BOLD : 0);
+}
+
+void init_aewl() {
+ AewlAttrSettings ats = {
+ {
+ curses_attr_for_pair(7, 0, false), /* text */
+ curses_attr_for_pair(7, 0, true), /* text focus */
+ curses_attr_for_pair(1, 0, false), /* text shortcut */
+ curses_attr_for_pair(1, 0, true) /* text shortcut focus */
+ },
+
+ {
+ curses_attr_for_pair(7, 4, false), /* button */
+ curses_attr_for_pair(7, 2, true), /* button focus */
+ curses_attr_for_pair(1, 4, false), /* button shortcut */
+ curses_attr_for_pair(1, 2, true) /* button shortcut focus */
+ },
+
+ {
+ curses_attr_for_pair(7, 0, false), /* frame */
+ curses_attr_for_pair(7, 0, true), /* frame focus */
+ curses_attr_for_pair(1, 0, false), /* frame shortcut */
+ curses_attr_for_pair(1, 0, true) /* frame shortcut focus */
+ },
+
+ {
+ curses_attr_for_pair(7, 0, false), /* field */
+ curses_attr_for_pair(7, 0, true), /* field focus */
+ curses_attr_for_pair(7, 4, false), /* field selection */
+ curses_attr_for_pair(7, 1, true) /* field selection focus */
+ },
+
+ curses_attr_for_pair(0, 0, true) /* field pad char */
+ };
+
+ aewl_init(&ats);
+}
+
diff --git a/init_aewl.h b/init_aewl.h
new file mode 100644
index 0000000..d23f1e5
--- /dev/null
+++ b/init_aewl.h
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef btco_aewan_init_aewl_h
+#define btco_aewan_init_aewl_h
+
+/* initializes the aewl widget library by passing to it
+ * our application-specific settings */
+void init_aewl();
+
+#endif
+
diff --git a/keybind.c b/keybind.c
new file mode 100644
index 0000000..e7b799e
--- /dev/null
+++ b/keybind.c
@@ -0,0 +1,97 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include <stdlib.h>
+#include <ncurses.h>
+#include "bores/bores.h"
+
+#include "keybind.h"
+#include "keys.h"
+#include "commands.h"
+
+/* This array represents the current key map: cmdforkey[key] is
+ * the command the key is bound to (0 if the key is not bound) */
+#define KEYCODE_MAX 512
+static int *cmdforkey;
+
+void keybind_init(void) {
+ /* allocate it (remember that zalloc() already zeroes it out) */
+ cmdforkey = zalloc(sizeof(int) * KEYCODE_MAX);
+
+ /* assign defaults */
+ cmdforkey[KEY_CTRL_C] = COMMAND_QUIT;
+ cmdforkey[KEY_CTRL_A] = COMMAND_ADD_LAYER_DEFAULTS;
+ cmdforkey[KEY_ALT_A] = COMMAND_ADD_LAYER_SPECIFY;
+ cmdforkey[KEY_ALT_F] = COMMAND_SET_FOREGROUND;
+ cmdforkey[KEY_ALT_B] = COMMAND_SET_BACKGROUND;
+ cmdforkey[KEY_CTRL_I] = COMMAND_SHOW_COLOR_DLG;
+ cmdforkey[KEY_CTRL_O] = COMMAND_LOAD_FILE;
+ cmdforkey[KEY_CTRL_S] = COMMAND_SAVE_FILE;
+ cmdforkey[KEY_CTRL_E] = COMMAND_EDIT_META;
+ cmdforkey[KEY_LEFT] = COMMAND_MOVE_LEFT;
+ cmdforkey[KEY_UP] = COMMAND_MOVE_UP;
+ cmdforkey[KEY_DOWN] = COMMAND_MOVE_DOWN;
+ cmdforkey[KEY_RIGHT] = COMMAND_MOVE_RIGHT;
+ cmdforkey[10] = COMMAND_CARRIAGE_RETURN;
+ cmdforkey[KEY_NPAGE] = COMMAND_PAGE_DOWN;
+ cmdforkey[KEY_PPAGE] = COMMAND_PAGE_UP;
+ cmdforkey[KEY_HOME] = COMMAND_START_OF_LINE;
+ cmdforkey[KEY_END] = COMMAND_END_OF_LINE;
+ cmdforkey[KEY_CTRL_Z] = COMMAND_FAST_LEFT;
+ cmdforkey[KEY_CTRL_X] = COMMAND_FAST_RIGHT;
+ cmdforkey[KEY_ALT_P] = COMMAND_PICK_COLOR;
+ cmdforkey[KEY_ALT_Z] = COMMAND_TINT_CELL;
+ cmdforkey[KEY_ALT_S] = COMMAND_TOGGLE_SELECTION;
+ cmdforkey[27] = COMMAND_CANCEL;
+ cmdforkey[KEY_CTRL_L] = COMMAND_SHOW_LAYER_DLG;
+ cmdforkey[KEY_CTRL_W] = COMMAND_NEXT_LAYER;
+ cmdforkey[KEY_CTRL_Q] = COMMAND_PREV_LAYER;
+ cmdforkey[KEY_CTRL_D] = COMMAND_DUP_LAYER;
+ cmdforkey[KEY_CTRL_R] = COMMAND_RENAME_LAYER;
+ cmdforkey[KEY_CTRL_G] = COMMAND_TOGGLE_LINE_MODE;
+ cmdforkey[KEY_CTRL_P] = COMMAND_TOGGLE_COMPOSITE;
+ cmdforkey[KEY_IC] = COMMAND_TOGGLE_INSERT;
+ cmdforkey[KEY_ALT_R] = COMMAND_RESIZE_LAYER;
+}
+
+int keybind_translate(int key) {
+ /* do special 'untranslation' of keys for the cases when curses
+ * is a little _too_ helpful and gives us key codes that are much
+ * more abstract than we need. */
+ if (key == KEY_SUSPEND) key = KEY_CTRL_Z;
+
+ /* now translate */
+ return cmdforkey[key];
+}
+
+
diff --git a/keybind.h b/keybind.h
new file mode 100644
index 0000000..a8413aa
--- /dev/null
+++ b/keybind.h
@@ -0,0 +1,50 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef btco_aewan_keybind_h
+#define btco_aewan_keybind_h
+
+/* Initializes the keybindings to "factory default". This must be called
+ * on startup, since the keymap will contain trash unless it is explicitly
+ * initialized. */
+void keybind_init(void);
+
+/* TODO: insert functions for loading user's custom keybinding from
+ * his .aewanrc file or something */
+
+/* Returns which command the given key corresponds to. Returns
+ * COMMAND_UNDEFINED if it does not correspond to any command. */
+int keybind_translate(int key);
+
+#endif
+
diff --git a/keys.c b/keys.c
new file mode 100644
index 0000000..5239e51
--- /dev/null
+++ b/keys.c
@@ -0,0 +1,64 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include <ncurses.h>
+
+#include "keys.h"
+
+void keys_init() {
+ int i;
+ char seq[] = "\ex";
+ for (i = KEY_ALT_A; i <= KEY_ALT_Z; i++) {
+ seq[1] = i - KEY_ALT_A + 'a';
+ define_key(seq, i);
+ }
+
+ /* xterm, support */
+ define_key("\e[1;2A", KEY_UP); /* shift + up */
+ define_key("\e[1;2B", KEY_DOWN); /* shift + down */
+ define_key("\e[1;2C", KEY_RIGHT); /* shift + right */
+ define_key("\e[1;2D", KEY_LEFT); /* shift + left */
+
+ /* rxvt support */
+ define_key("\e[[a", KEY_UP); /* shift + up */
+ define_key("\e[[b", KEY_DOWN); /* shift + down */
+ define_key("\e[[c", KEY_RIGHT); /* shift + right */
+ define_key("\e[[d", KEY_LEFT); /* shift + left */
+ define_key("\e[7~", KEY_HOME); /* home key */
+ define_key("\e[8~", KEY_END); /* end key */
+ define_key("\e[11~", KEY_F(1));
+ define_key("\e[12~", KEY_F(2));
+ define_key("\e[13~", KEY_F(3));
+ define_key("\e[14~", KEY_F(4));
+}
+
diff --git a/keys.h b/keys.h
new file mode 100644
index 0000000..4a98334
--- /dev/null
+++ b/keys.h
@@ -0,0 +1,99 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_keys_h
+#define _btco_aewan_keys_h
+
+/* If you are going to change this, please keep in mind that KEY_ALT_A thru
+ * KEY_ALT_Z must have contiguous values. */
+#define KEY_ALT_A 400
+#define KEY_ALT_B 401
+#define KEY_ALT_C 402
+#define KEY_ALT_D 403
+#define KEY_ALT_E 404
+#define KEY_ALT_F 405
+#define KEY_ALT_G 406
+#define KEY_ALT_H 407
+#define KEY_ALT_I 408
+#define KEY_ALT_J 409
+#define KEY_ALT_K 410
+#define KEY_ALT_L 411
+#define KEY_ALT_M 412
+#define KEY_ALT_N 413
+#define KEY_ALT_O 414
+#define KEY_ALT_P 415
+#define KEY_ALT_Q 416
+#define KEY_ALT_R 417
+#define KEY_ALT_S 418
+#define KEY_ALT_T 419
+#define KEY_ALT_U 420
+#define KEY_ALT_V 421
+#define KEY_ALT_W 422
+#define KEY_ALT_X 423
+#define KEY_ALT_Y 424
+#define KEY_ALT_Z 425
+
+#define KEY_CTRL_A 1
+#define KEY_CTRL_B 2
+#define KEY_CTRL_C 3
+#define KEY_CTRL_D 4
+#define KEY_CTRL_E 5
+#define KEY_CTRL_F 6
+#define KEY_CTRL_G 7
+#define KEY_CTRL_H 8
+#define KEY_CTRL_I 9
+#define KEY_CTRL_J 10
+#define KEY_CTRL_K 11
+#define KEY_CTRL_L 12
+#define KEY_CTRL_M 13
+#define KEY_CTRL_N 14
+#define KEY_CTRL_O 15
+#define KEY_CTRL_P 16
+#define KEY_CTRL_Q 17
+#define KEY_CTRL_R 18
+#define KEY_CTRL_S 19
+#define KEY_CTRL_T 20
+#define KEY_CTRL_U 21
+#define KEY_CTRL_V 22
+#define KEY_CTRL_W 23
+#define KEY_CTRL_X 24
+#define KEY_CTRL_Y 25
+#define KEY_CTRL_Z 26
+
+
+/* register keys in curses */
+void keys_init(void);
+
+#endif
+
diff --git a/layer.c b/layer.c
new file mode 100644
index 0000000..9b761f6
--- /dev/null
+++ b/layer.c
@@ -0,0 +1,314 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+#include <stdlib.h>
+#include <string.h>
+#include <ncurses.h>
+
+#include "layer.h"
+#include "chtr.h"
+
+const Cell BLANK_CELL = { ' ', 0x70 };
+
+Layer *layer_create(const char *layer_name, int width, int height) {
+ int i, j;
+ Layer *layer = (Layer *) zalloc(sizeof(Layer));
+
+ layer->name = 0;
+ dstrset(&layer->name, layer_name);
+ layer->width = width;
+ layer->height = height;
+ layer->visible = true;
+ layer->transp = false;
+
+ layer->cells = (Cell**) zalloc(width * sizeof(Cell*));
+ for (i = 0; i < width; i++) {
+ layer->cells[i] = (Cell*) zalloc(height * sizeof(Cell));
+ for (j = 0; j < height; j++) {
+ layer->cells[i][j].ch = ' ';
+ layer->cells[i][j].attr = 0x70;
+ }
+ }
+
+ return layer;
+}
+
+void layer_destroy(Layer *layer) {
+ int i;
+ if (!layer) return;
+ dstrset(&layer->name, 0);
+
+ for (i = 0; i < layer->width; i++) free(layer->cells[i]);
+ free(layer->cells);
+}
+
+bool is_cell_transp(const Cell *c) {
+ return c->ch == ' ' && c->attr == 0x70;
+}
+
+void layer_blit(Layer *src, int xsrc, int ysrc, int width, int height,
+ Layer *dst, int xdst, int ydst) {
+ int dx, dy;
+ int src_x, src_y, dst_x, dst_y;
+
+ /* brace your self to read the most inefficient blit code you have
+ * ever read in your life. The following algorithm makes bubble-sort
+ * look blazing fast. */
+ for (dx = 0; dx < width; dx++) {
+ for (dy = 0; dy < height; dy++) {
+ src_x = xsrc + dx;
+ src_y = ysrc + dy;
+ dst_x = xdst + dx;
+ dst_y = ydst + dy;
+
+ if (!layer_valid_cell(src, src_x, src_y) ||
+ !layer_valid_cell(dst, dst_x, dst_y)) continue;
+
+ if (src->transp &&
+ is_cell_transp(&src->cells[src_x][src_y])) continue;
+
+ dst->cells[dst_x][dst_y] = src->cells[src_x][src_y];
+ }
+ }
+}
+
+
+bool layer_valid_cell(Layer *layer, int x, int y) {
+ return (x >= 0 && x < layer->width && y >= 0 && y < layer->height);
+}
+
+void layer_paint(Layer *layer, int x0, int y0, int xclip, int yclip,
+ int wclip, int hclip,
+ void (*modify)(int x, int y, int *ch, int *attr)) {
+
+ int x, xi, xf; int y, yi, yf; int ch, attr;
+
+ interval_intersect(x0 , x0 + layer->width - 1,
+ xclip, xclip + wclip - 1, &xi, &xf);
+ interval_intersect(y0 , y0 + layer->height - 1,
+ yclip, yclip + hclip - 1, &yi, &yf);
+
+ for (x = xi; x <= xf; x++) for (y = yi; y <= yf; y++) {
+ if (!kurses_move(x, y)) continue;
+ ch = layer->cells[x - x0][y - y0].ch;
+ attr = layer->cells[x - x0][y - y0].attr;
+
+ if (modify) (*modify)(x - x0, y - y0, &ch, &attr);
+
+ if (layer->transp &&
+ is_cell_transp(&layer->cells[x - x0][y - y0])) continue;
+
+ kurses_color(attr >> 4, attr & 0x0F);
+ addch(chtr_a2c(ch));
+ }
+}
+
+void layer_paint_opaque(Layer *layer, int x0, int y0, int xclip, int yclip,
+ int wclip, int hclip,
+ void (*modify)(int x, int y, int *ch, int *attr)) {
+ bool backup = layer->transp;
+ layer->transp = false;
+ layer_paint(layer, x0, y0, xclip, yclip, wclip, hclip, modify);
+ layer->transp = backup;
+
+ /* I agree, this is a monument to sloppiness.
+ * But it works, and does what is promised by the documentation. */
+}
+
+Layer *layer_dup(const char *layer_name, Layer *model) {
+ Layer *l;
+ if (!model) return NULL;
+
+ l = layer_create(layer_name, model->width, model->height);
+ l->transp = model->transp;
+ layer_blit(model, 0, 0, model->width, model->height, l, 0, 0);
+ return l;
+}
+
+/* table is a vector of two strings. If ch is found in table[0] at position n,
+ * return value is table[1][n]. Else, return value is ch.
+ * table[0] and table[1] are assumed to be of the same size. */
+static char tbl_lookup(char **table, int ch) {
+ const char *s = table[0], *p = table[1];
+ while (*s) {
+ if (*(s++) == ch) return *p;
+ p++;
+ }
+ return ch;
+}
+
+void layer_flip_x(Layer *layer, bool flipchars) {
+ Layer *tmp;
+ int x, y;
+ static char *flip_table[2] = {
+ "`'()/\\<>[]{}\x03\x05\x06\x08\x09\x0b", /* funny hex chars are line */
+ "'`)(\\/><][}{\x05\x03\x08\x06\x0b\x09" /* drawing chars (see chtr.h) */
+ };
+
+ tmp = layer_dup("tmp", layer);
+ for (y = 0; y < layer->height; y++) {
+ for (x = 0; x < layer->width; x++) {
+ Cell c = tmp->cells[x][y];
+ if (flipchars) c.ch = tbl_lookup(flip_table, c.ch);
+
+ layer->cells[layer->width - x - 1][y] = c;
+ }
+ }
+
+ layer_destroy(tmp);
+}
+
+void layer_flip_y(Layer *layer, bool flipchars) {
+ Layer *tmp;
+ int x, y;
+ static char *flip_table[2] = {
+ "/\\\x03\x09\x04\x0a\x05\x0b",
+ "\\/\x09\x03\x0a\x04\x0b\x05"
+ };
+
+ tmp = layer_dup("tmp", layer);
+ for (y = 0; y < layer->height; y++) {
+ for (x = 0; x < layer->width; x++) {
+ Cell c = tmp->cells[x][y];
+ if (flipchars) c.ch = tbl_lookup(flip_table, c.ch);
+
+ layer->cells[x][layer->height - y - 1] = c;
+ }
+ }
+
+ layer_destroy(tmp);
+}
+
+void layer_save(Layer *lyr, AeFile *f) {
+ int x, y;
+ char *buf = zalloc(lyr->width * 4 + 1);
+
+ aeff_write_header(f, "Layer");
+ aeff_write_string(f, "name", lyr->name ? lyr->name : "unnamed");
+ aeff_write_int(f, "width", lyr->width);
+ aeff_write_int(f, "height", lyr->height);
+ aeff_write_bool(f, "visible", lyr->visible);
+ aeff_write_bool(f, "transparent", lyr->transp);
+
+ for (y = 0; y < lyr->height; y++) {
+ /* fill in buf with current line (decoded into hex duplets) */
+ for (x = 0; x < lyr->width; x++) {
+ chr2hex(lyr->cells[x][y].ch, &buf[x * 4]);
+ chr2hex(lyr->cells[x][y].attr, &buf[x * 4 + 2]);
+ }
+
+ /* save line to file */
+ aeff_write_string(f, "layer-line", buf);
+ }
+
+ aeff_write_footer(f, "Layer");
+ zfree(&buf);
+}
+
+Layer *layer_load(AeFile *f) {
+ int x, y;
+ char *buf = 0;
+ Layer *lyr = NULL;
+ char *name = 0;
+ int width, height;
+
+ if (!aeff_read_header(f, "Layer")) goto exception;
+ if (!aeff_read_string(f, "name", &name)) goto exception;
+ if (!aeff_read_int(f, "width", &width)) goto exception;
+ if (!aeff_read_int(f, "height", &height)) goto exception;
+
+ lyr = layer_create(name, width, height);
+ zfree(&name);
+
+ if (!aeff_read_bool(f, "visible", &lyr->visible)) goto exception;
+ if (!aeff_read_bool(f, "transparent", &lyr->transp)) goto exception;
+
+ for (y = 0; y < lyr->height; y++) {
+ if (!aeff_read_string(f, "layer-line", &buf)) goto exception;
+
+ if (strlen(buf) != lyr->width * 4) {
+ aeff_set_error("layer-line line has incorrect width");
+ goto exception;
+ }
+
+ /* interpret buf as width*4 hex duplets specifying char and attribute
+ * for each cell in the line */
+ for (x = 0; x < lyr->width; x++) {
+ lyr->cells[x][y].ch = hex2chr(&buf[x * 4]);
+ lyr->cells[x][y].attr = hex2chr(&buf[x * 4 + 2]);
+ }
+
+ zfree(&buf);
+ }
+
+ aeff_read_footer(f, "Layer");
+
+ return lyr;
+
+exception:
+ if (lyr) layer_destroy(lyr);
+ if (buf) zfree(&buf);
+ return NULL;
+}
+
+Layer *layer_load_OLD(FILE *f) {
+ char *lyr_name;
+ char signature[3];
+ int width, height, x, y;
+ bool v, t;
+ Layer *l;
+
+ signature[0] = fgetc(f);
+ signature[1] = fgetc(f);
+ signature[2] = 0;
+
+ if (strcmp(signature, "L3")) return NULL; /* unknown format */
+ if ( !(lyr_name = floadstr(f)) ) return NULL;
+ fread(&width, sizeof(int), 1, f);
+ fread(&height, sizeof(int), 1, f);
+ v = fgetc(f) ? true : false;
+ t = fgetc(f) ? true : false;
+
+ l = layer_create(lyr_name, width, height);
+ l->visible = v;
+ l->transp = t;
+
+ for (x = 0; x < width; x++) for (y = 0; y < height; y++) {
+ l->cells[x][y].ch = fgetc(f);
+ l->cells[x][y].attr = fgetc(f);
+ }
+
+ return l;
+}
+
diff --git a/layer.h b/layer.h
new file mode 100644
index 0000000..cfdb853
--- /dev/null
+++ b/layer.h
@@ -0,0 +1,144 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_layer_h
+#define _btco_aewan_layer_h
+
+#include <stdbool.h>
+#include "bores/bores.h"
+#include <stdio.h>
+#include "aeff.h"
+
+struct _Cell {
+ unsigned char ch; /* character that occupies this cell.
+ * Since a control character may never be in a cell,
+ * aewan uses some characters in the 0-31 range to
+ * represent vt100 line graphics characters and
+ * other special characters. See the chtr.h
+ * file for more details. */
+
+ unsigned char attr; /* attribute of the character */
+};
+typedef struct _Cell Cell;
+
+struct _Layer {
+ char *name; /* name of this layer */
+ int width, height; /* width and height of layer, in cells */
+ Cell **cells; /* indexed cells[0][0] to cells[width-1][height-1] */
+ bool visible; /* whether visibility for this layer is enabled */
+ bool transp; /* whether this layer has transparency enabled.
+ * Upon blit and paint operations, transparent
+ * cells will not be drawn. */
+};
+typedef struct _Layer Layer;
+
+/* A blank cell. */
+extern const Cell BLANK_CELL;
+
+/* Creates a new, empty layer with the specified dimensions.
+ * Sets the layer name to <layer_name>. Returns a pointer to the newly
+ * created layer. */
+Layer *layer_create(const char *layer_name, int width, int height);
+
+/* Creates a new layer that is an exact copy of the given layer,
+ * except possibly for the name. Returns a pointer to the newly created
+ * layer */
+Layer *layer_dup(const char *layer_name, Layer *model);
+
+/* Destroys a layer previously created with layer_create */
+void layer_destroy(Layer *layer);
+
+/* Copies part of or the totality of the contents of the source layer onto
+ * the destination layer. The source rectangle for the copy is given
+ * by xsrc, ysrc, width and height; the destination rectangle is given
+ * by xdst, ydst, width and height. */
+void layer_blit(Layer *src, int xsrc, int ysrc, int width, int height,
+ Layer *dst, int xdst, int ydst);
+
+/* Paints the given layer on the screen, placing its top-left corner
+ * at the given coordinates x0, y0, which may be negative. The clipping
+ * rectangle is given by xclip, yclip, wclip and hclip.
+ *
+ * Painting code allows custom modification of output through
+ * a call to the modify function. If <modify> is not NULL, it
+ * will be called for every cell drawn, and it can modify the
+ * color.
+ *
+ * Please note that this function pays no attention to the layer's
+ * 'visible' flag: it draws it regardless. It DOES pay attention
+ * to the 'transparent' flag.
+ */
+void layer_paint(Layer *layer, int x0, int y0, int xclip, int yclip,
+ int wclip, int hclip,
+ void (*modify)(int x, int y, int *ch, int *attr));
+
+/* Same as layer_paint, but forces opaque rendering, that is, transparent
+ * cells will be rendered as white-foreground, black-background spaces. */
+void layer_paint_opaque(Layer *layer, int x0, int y0, int xclip, int yclip,
+ int wclip, int hclip,
+ void (*modify)(int x, int y, int *ch, int *attr));
+
+/* Returns whether the given (x, y) coordinates are valid within
+ * layer lyr, that is, returns true if and only if 0 <= x <= lyr->width
+ * and 0 <= y <= lyr->height */
+bool layer_valid_cell(Layer *layer, int x, int y);
+
+/* Performs a vertical mirroring operation on the given layer.
+ * The <flipchars> parameter indicates whether characters themselves
+ * should be "flipped" to their mirrored counterparts (e.g.
+ * change '>' to '<', etc). */
+void layer_flip_x(Layer *layer, bool flipchars);
+
+/* Performs a horizontal mirroring operation on the given layer.
+ * The <flipchars> parameter indicates whether characters themselves
+ * should be "flipped" to their mirrored counterpars (e.g.
+ * change '\' to '/' */
+void layer_flip_y(Layer *layer, bool flipchars);
+
+/* Writes layer's data to file f */
+void layer_save(Layer *lyr, AeFile *f);
+
+/* Attempts to load layer from file f; if loading succeeds, returns
+ * a pointer to a dynamically allocated layer that corresponds
+ * to the loaded data; if an error occurs, returns NULL. */
+Layer *layer_load(AeFile *f);
+
+/* Loads a layer in the OLD binary format */
+Layer *layer_load_OLD(FILE *f);
+
+/* Returns whether the given cell is considered transparent or not */
+bool is_cell_transp(const Cell* c);
+
+#endif
+
diff --git a/layerdlg.c b/layerdlg.c
new file mode 100644
index 0000000..ffddb5d
--- /dev/null
+++ b/layerdlg.c
@@ -0,0 +1,168 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+#include <ncurses.h>
+
+#include "document.h"
+#include "colordlg.h"
+#include "psd.h"
+#include "absmenu.h"
+
+/* DLG_W
+- ,---------------------------,
+D | - |
+L | : LIST_H |
+G | : |
+| | : |
+H | - |
+: +---------------------------+
+: | A |
+: | |
+: | |
+: | |
+- `---------------------------'
+*/
+
+#define DLG_W 42
+#define DLG_H 19
+#define LIST_H 11
+
+static AbsMenu *menu = 0;
+
+static void painter(int i, AbsMenu *m) {
+ Layer *l = _doc->layers[i];
+ printw("%2d: %c%c (%3d x %3d) %s", i,
+ l->visible ? 'v' : ' ',
+ l->transp ? 't' : ' ',
+ l->width, l->height, (l->name ? l->name : "(untitled)"));
+}
+
+static void paint_dlg(void) {
+ int x0, y0; int x, y;
+
+ kurses_color(7, 0);
+ draw_centered_window(DLG_W, DLG_H, "Layer Manager", &x0, &y0);
+
+ if (!menu) {
+ menu = menu_create(&(_doc->layer_count), x0,
+ y0, DLG_W - 2, LIST_H,
+ 0x71, 0x70, painter);
+ menu_select_item(menu, _lyr);
+ }
+
+ draw_hline(x0 - 1, y0 + LIST_H, DLG_W, ACS_LTEE, ACS_HLINE, ACS_RTEE);
+
+ /* print instructions */
+ kurses_move(x = x0 + 1, y = y0 + LIST_H + 1);
+
+ kurses_color(2, 0); addch('<'); addch(ACS_LRCORNER); addch(' ');
+ kurses_color(7, 0);
+ printw(": go to layer");
+
+ kurses_move(x, ++y);
+ kurses_color(2, 0); addstr("d "); kurses_color(7, 0);
+ printw(": delete layer");
+
+ kurses_move(x, ++y);
+ kurses_color(2, 0); addstr("+/-"); kurses_color(7, 0);
+ printw(": move layer up/down");
+
+ kurses_move(x, ++y);
+ kurses_color(2, 0); addstr("v "); kurses_color(7, 0);
+ printw(": toggle visibility");
+
+ kurses_move(x, ++y);
+ kurses_color(2, 0); addstr("t "); kurses_color(7, 0);
+ printw(": toggle transparency");
+
+ menu_paint(menu);
+}
+
+void show_layer_dlg(void) {
+ int ch; int quit = 0;
+ Layer *lyr;
+
+ menu = 0;
+
+ while (!quit) {
+ paint_dlg();
+ refresh();
+ ch = getch();
+ switch (ch) {
+ case 10: switch_to_layer(menu->sel_item);
+ /* fall through */
+ case 27: case 3: case 7: quit = 1; break;
+ case 'd': /* delete layer */
+ document_del_layer(_doc, menu->sel_item);
+ if (_doc->layer_count == 0) /* no layers, so close dialog */
+ quit = 1;
+ else if (menu->sel_item >= _doc->layer_count)
+ menu->sel_item = _doc->layer_count - 1;
+ break;
+ case '+': case '=': /* move layer up */
+ if (menu->sel_item > 0) {
+ int i = menu->sel_item; Layer **ls = _doc->layers;
+ Layer* l = ls[i-1];
+ ls[i-1] = ls[i];
+ ls[i] = l;
+
+ menu->sel_item--;
+ }
+ break;
+ case '-': case '_':
+ if (menu->sel_item < _doc->layer_count - 1) {
+ int i = menu->sel_item; Layer **ls = _doc->layers;
+ Layer* l = ls[i+1];
+ ls[i+1] = ls[i];
+ ls[i] = l;
+
+ menu->sel_item++;
+ }
+ break;
+ case 'v': /* toggle layer visibility */
+ lyr = _doc->layers[menu->sel_item];
+ lyr->visible = !lyr->visible;
+ break;
+ case 't': /* toggle layer transparency */
+ lyr = _doc->layers[menu->sel_item];
+ lyr->transp = !lyr->transp;
+ break;
+
+ default: if (menu) menu_handle_key(menu, ch);
+ }
+ }
+
+ if (menu) menu_destroy(menu);
+}
+
diff --git a/layerdlg.h b/layerdlg.h
new file mode 100644
index 0000000..424e540
--- /dev/null
+++ b/layerdlg.h
@@ -0,0 +1,45 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_layerdlg_h
+#define _btco_aewan_layerdlg_h
+
+/* Shows the layer management dialog. Through it, the user will be able
+ * to switch to a different layer, delete layers, swap layers,
+ * toggle the transparency flag in layers, etc. Returns when the user
+ * is done. */
+void show_layer_dlg(void);
+
+#endif
+
diff --git a/make-package.sh b/make-package.sh
new file mode 100644
index 0000000..f697209
--- /dev/null
+++ b/make-package.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+if ! [ -f configure ]; then
+ echo "./configure does not exist. Run autoconf."
+ exit 1
+fi
+
+/bin/rm -rf autom4te.cache
+
+X=`tempfile`
+/bin/rm -f $X
+mkdir $X
+
+BASENAME=aewan-`cat version.h | grep AEWAN_PROGRAM_VERSION | grep -v AEWAN_PROGRAM_VERSION_NAME | cut -d\" -f2`
+
+(cd .. && cp -a aewan $X/$BASENAME)
+(cd $X && find $X -name CVS -type d -exec rm -rf {} \; 2>/dev/null )
+
+(cd $X && tar -zc $BASENAME) > ../$BASENAME.tar.gz
+
+/bin/rm -rf $X
+echo "../$BASENAME.tar.gz generated."
+
diff --git a/man/man1/aecat.1 b/man/man1/aecat.1
new file mode 100644
index 0000000..36dfabd
--- /dev/null
+++ b/man/man1/aecat.1
@@ -0,0 +1,63 @@
+.TH aecat "1" "March 2005" "aecat (Aewan Ascii Art Editor)"
+.SH NAME
+aecat \- display an aewan document
+.SH SYNOPSIS
+.B aecat
+[-b] [-c] [-{n|N}] [{-p | -l <layer_num>}] [-f <format>] [-o <output_file>] inputfile
+
+.SH DESCRIPTION
+This is an utility program that will convert an aewan document
+to ANSI escape sequences so that it can be rendered on a standard
+terminal. Alternatively, it can also generate HTML code for displaying
+the document in a web page. Any particular layer of the document
+may be converted, or you may request a composite of all layers.
+
+.SH OPTIONS
+.TP
+\fB\-f\fR
+specifies output format - can "text", "html" or "comment". Default is "text".
+The "comment" format extracts document metadata.
+.TP
+\fB\-c\fR
+prepend a 'clear screen' escape sequence (only valid when outputting
+text).
+.TP
+\fB\-o\fR\fI<file>\fR
+writes output to specified file rather than stdout
+.TP
+\fB\-b\fR
+disables output of color (only characters will be printed).
+.TP
+\fB\-l\fR\fI<layer_no>\fR
+specifies which layer of the document is to be used
+(must be an index, not a layer name). By default, layer 0 will be used.
+.TP
+\fB\-L\fR
+displays the number of layers in the file.
+.TP
+\fB\-p\fR
+exports a composite, that is, overlays all visible layers,
+paying attention to layer transparency, etc. The size of the
+composite will be the size of the first layer
+.TP
+\fB\-n\fR
+suppress output of newlines
+.TP
+\fB\-h\fR
+prints a short help text
+
+.SH AUTHORS
+This program is part of the Aewan Ascii Art Editor package.
+See aewan(1) for author information.
+
+.SH LICENSE
+Copyright (c) 2004-2005 Bruno Takahashi C. de Oliveira. All rights reserved.
+
+This program is licensed under the GNU General Public License,
+version 2 or, at your option, any later version. For full license
+information, please refer to the COPYING file that accompanies
+the program.
+
+.SH SEE ALSO
+\fBaewan\fR(1), \fBaewan\fR(5), \fBaemakeflic\fR(1)
+
diff --git a/man/man1/aemakeflic.1 b/man/man1/aemakeflic.1
new file mode 100644
index 0000000..b5cdd95
--- /dev/null
+++ b/man/man1/aemakeflic.1
@@ -0,0 +1,50 @@
+.TH aemakeflic "1" "September 2005" "aemakeflic (Aewan Ascii Art Editor)"
+.SH NAME
+aemakeflic \- produce an animation from an aewan document
+.SH SYNOPSIS
+.B aemakeflic
+[-f {less|sh}] [-N] [-b] [-d <delay>] input.ae [outputfile.ext]
+
+.SH DESCRIPTION
+This utility will make an ascii animation out of an aewan document. It
+can currently produce animations in two formats: a shellscript which,
+when executed, will display the animation and a "less movie" intended
+to be "played" on the very popular 'less' output pager -- that is, the
+user will see the animation as he pages down through the file in an
+appropriate window size.
+
+Each layer in the aewan document is interpreted as one frame of the animation.
+Layer transparency and compositing are not used: each layer becomes a frame.
+
+.SH OPTIONS
+.TP
+\fB\-f\fR
+specifies output format - can "sh" for a shellscript or "less" for a
+"less movie"
+.TP
+\fB\-N\fR
+omit the initial instructions that are normally included in the resulting
+file. The instructions will orient the user as to how to play the file.
+.TP
+\fB\-b\fR
+disables output of color (only characters will be printed).
+.TP
+\fB\-d delay\fR
+specifies the delay between frames (for shellscript only), given in
+milliseconds.
+
+.SH AUTHORS
+This program is part of the Aewan Ascii Art Editor package.
+See aewan(1) for author information.
+
+.SH LICENSE
+Copyright (c) 2004-2005 Bruno Takahashi C. de Oliveira. All rights reserved.
+
+This program is licensed under the GNU General Public License,
+version 2 or, at your option, any later version. For full license
+information, please refer to the COPYING file that accompanies
+the program.
+
+.SH SEE ALSO
+\fBaewan\fR(1), \fBaewan\fR(5), \fBaecat\fR(1)
+
diff --git a/man/man1/aewan.1 b/man/man1/aewan.1
new file mode 100644
index 0000000..d50b64e
--- /dev/null
+++ b/man/man1/aewan.1
@@ -0,0 +1,50 @@
+.TH aewan "1" "August 2004" "aewan (Aewan Ascii Art Editor)"
+
+.SH NAME
+aewan \- An ascii-art editor
+
+.SH SYNOPSIS
+.B aewan [\fIfilename\fR]
+.SH DESCRIPTION
+.PP
+Aewan is a multi-layered ascii-art/animation editor that produces both
+stand-alone cat-able art files and an easy-to-parse format for integration in
+your terminal applications (for information about the file format,
+see the aewan(5) manpage).
+
+If you invoke the program without a command-line argument, it will
+open an untitled document for you to edit. If you supply an argument,
+it must be the name of an aewan file you wish to open. That file
+must exist, or an error will occur.
+
+.SH PROJECT HOME PAGE
+The Aewan Project's official homepage is the following:
+
+
+ \fBhttp://aewan.sourceforge.net\fR
+
+There you will find author information, FAQ, links to the latest
+version of the program, etc.
+
+.SH AUTHORS
+The developers can be contacted through the following e-mail address:
+
+ \fBaewan-devel@lists.sf.net\fR
+
+People who have worked or are currently working on this project:
+
+ * Bruno T. C. de Oliveira (brunotc@gmail.com)
+ * Peep Pullerits (http://solicit.estprog.ee; solicit@estprog.ee)
+ * Praveen Kurup <praveen_kurup@jasubhai.com>
+ * Gerfried Fuchs <alfie@ist.org>
+
+.SH LICENSE INFORMATION
+Copyright (c) 2004 Bruno Takahashi C. de Oliveira. All rights reserved.
+
+This program is licensed under the GNU General Public License,
+version 2 or, at your option, any later version. For full license
+information, please refer to the COPYING file that accompanies
+the program.
+
+.SH SEE ALSO
+\fBaecat\fR(1), \fBaewan\fR(5)
diff --git a/man/man5/aewan.5 b/man/man5/aewan.5
new file mode 100644
index 0000000..d4d3cee
--- /dev/null
+++ b/man/man5/aewan.5
@@ -0,0 +1,108 @@
+.TH aewan "5" "August 2005" "aewan (Aewan Ascii Art Editor)"
+
+.SH NAME
+aewan \- File format documentation
+
+.SH INTRODUCTION
+Starting with version 0.9.0, Aewan features an all-new, easier to parse
+file format. Prior versions used a binary (largely undocumented) file
+format, and relied on a program (ae2aes) to convert it to a readable
+format. With the new format, the ae2aes utility became unnecessary
+and was deprecated.
+
+An aewan document is a gzipped file. Therefore, you must first gunzip
+it in order to be able to parse its contents. On the command line, you
+could use \fIzcat\fR or something of the sort. On a program, you will
+probably want to use the \fIzlib\fR library.
+
+In the future it might be better for Aewan to supply a shared library
+to enable parsing of aewan files with minimal effort. Such a library would
+have to be integrated with the editor in order not to have to duplicate
+code (i.e. the editor itself would be just a client of the library).
+But for the time being, you have to read and parse the format
+on your own.
+
+.SH FILE FORMAT
+
+In the description below, the items in between brackets are NOT literal,
+they are placeholders. [S] is a placeholder for a string and [N] is a
+placeholder for a decimal integer, and [B] is a placeholder for a boolean
+value ('true' or 'false'). A line with "..." is not literal either, it
+just means that the lines above repeat a certain number of times.
+
+.nf
+<Aewan Document v1
+ layer-count: int: [N]
+ meta-info: str: [S]
+ <Layer
+ name: str: [S]
+ width: int: [N]
+ height: int: [N]
+ visible: bool: [B]
+ transparent: bool: [B]
+ layer-line: str: [S]
+ layer-line: str: [S]
+ layer-line: str: [S]
+ (...there are <height> such lines...)
+ >Layer
+ (...there are <layer-count> such blocks...)
+>Aewan Document v1
+.ff
+
+Indentation is ignored, but all other whitespace is significant.
+In particular, you can't omit the space that immediately follows
+the ':' field delimiters, or supply more than one space there.
+Notice that the file format does not use any quotation marks
+for the values, not even strings.
+
+.SH REPRESENTATION OF STRINGS
+Strings are represented almost literally in the file (where the [S]
+placeholders are in the blueprint above), and are not put in between
+quotes or anything. However, special characters (ASCII codes 1 to 31)
+are escaped: the escape code is a backslash, followed by the
+character '0' + ch, where ch is the special character. Thus, a newline
+character would be represented by "\\:", since ":" is '0' + 10.
+
+.SH REPRESENTATION OF INTEGERS AND BOOLEANS
+Integers use just the plain old decimal representation. The booleans
+are represented as strings: either "true" or "false" (without quotes).
+
+.SH REPRESENTATION OF LAYER LINES
+Each layer-line is a string, but it is specially formatted in order
+to convey the characters and attibutes in that line. In order to
+understand the format of a layer-line string, it is first necessary
+to introduce the concept of cells. A cell in an aewan layer is each
+of the spaces that can contain a character. A cell has two pieces
+of data: the character that is in it, and a color attribute.
+The character is just that: an 8-bit value represing the character
+drawn there. The color attribute is an 8-bit unsigned value that packs the
+foreground and background color of a given cell, as well as standout
+and blink attributes.
+
+The following color codes are used: 0=black, 1=red, 2=green,
+3=yellow, 4=blue, 5=magenta, 6=cyan, 7=white.
+
+The 8 bits of the attribute have the following meanings: SFFFLBBB.
+Where S is the standout bit, FFF is the 3-bit color code for
+the foreground color, L is the blink bit, and BBB is the
+3-bit color code for the background color.
+
+The layer-line string is composed of the hexadecimal representation
+of layer_width*2 bytes. Each 2 bytes is the information for one
+cell of the line: the first byte is the character, and the second
+is the attribute. For example, the hex representation for 'A' is
+0x41, so a line with five 'A's each of them in a different foreground
+color (but all with black background) would be represented as
+41104120413041404150.
+
+.SH LICENSE INFORMATION
+Copyright (c) 2004-2005 Bruno Takahashi C. de Oliveira. All rights reserved.
+
+This program is licensed under the GNU General Public License,
+version 2 or, at your option, any later version. For full license
+information, please refer to the COPYING file that accompanies
+the program.
+
+.SH SEE ALSO
+\fBaecat\fR(1), \fBaewan\fR(1)
+
diff --git a/menubar-items.inc b/menubar-items.inc
new file mode 100644
index 0000000..a1b4a6d
--- /dev/null
+++ b/menubar-items.inc
@@ -0,0 +1,77 @@
+static Menu menu[] = {
+ { "[F1] File", 1, 0, 0,
+ 7,
+ {
+ { 'N', "&New", COMMAND_NEW_FILE,
+ "Clears everything and starts from scratch" },
+ { 'L', "&Load...", COMMAND_LOAD_FILE,
+ "Loads a file into the editor" },
+ { 'S', "&Save", COMMAND_SAVE_FILE,
+ "Saves the current drawing" },
+ { 'A', "Save &As...", COMMAND_SAVE_FILE_AS,
+ "Saves the current drawing in a specified file" },
+ { 'M', "Edit &Meta...", COMMAND_EDIT_META,
+ "Opens an editor for you to edit this document's metadata" },
+ { ' ', "", COMMAND_UNDEFINED, NULL },
+ { 'Q', "&Quit", COMMAND_QUIT,
+ "Quits program" },
+ }
+ },
+
+ { "[F2] Edit", 16, 0, 0,
+ 8,
+ {
+ { 'C', "Drawing &color...", COMMAND_SHOW_COLOR_DLG,
+ "Brings up the color selection dialog" },
+ { 'I', "Toggle &Insert", COMMAND_TOGGLE_INSERT,
+ "Toggles insert/overwrite mode" },
+ { 'K', "Pic&k color", COMMAND_PICK_COLOR,
+ "Picks color under cursor to use as current color" },
+ { 'T', "&Tint cell", COMMAND_TINT_CELL,
+ "Applies current color to cell under cursor" },
+ { ' ', "", COMMAND_UNDEFINED, NULL },
+ { 'S', "Toggle &select mode", COMMAND_TOGGLE_SELECTION,
+ "Toggles select mode on/off" },
+ { 'L', "Toggle &line-drawing", COMMAND_TOGGLE_LINE_MODE,
+ "Toggles line-drawing mode on/off. Use 0-9 to draw lines" },
+ { 'P', "Toggle com&posite", COMMAND_TOGGLE_COMPOSITE,
+ "Toggles composite (all-layer) view on/off" },
+ }
+ },
+
+ { "[F3] Layer", 32, 0, 0,
+ 9,
+ {
+ { 'A', "&Add layer (defaults)", COMMAND_ADD_LAYER_DEFAULTS,
+ "Adds a layer with default parameters" },
+ { 'L', "Add &layer (specify)...", COMMAND_ADD_LAYER_SPECIFY,
+ "Adds a layer with custom parameters" },
+ { 'D', "&Duplicate layer", COMMAND_DUP_LAYER,
+ "Duplicates current layer. Copy is added to the bottom of the stack." },
+ { 'R', "&Rename layer...", COMMAND_RENAME_LAYER,
+ "Renames the current layer" },
+ { 'Z', "Resi&ze layer...", COMMAND_RESIZE_LAYER,
+ "Resizes the current layer" },
+ { 'M', "&Manage layers...", COMMAND_SHOW_LAYER_DLG,
+ "Shows a dialog in which you can manipulate layers" },
+ { ' ', "", COMMAND_UNDEFINED, NULL },
+ { 'N', "Go to &next layer", COMMAND_NEXT_LAYER,
+ "Goes to the next layer" },
+ { 'P', "Go to &previous layer", COMMAND_PREV_LAYER,
+ "Goes to the previous layer" },
+ }
+ },
+
+ { "[F4] Help", 64, 0, 0,
+ 3,
+ {
+ { 'K', "&Key reference", COMMAND_SHOW_HELP_DLG,
+ "Shows a table of keys and their functions" },
+ { ' ', "", COMMAND_UNDEFINED, NULL },
+ { 'A', "&About Aewan", COMMAND_SHOW_ABOUT_DLG,
+ "Shows information about the program" },
+ }
+ },
+};
+static int menu_count = 4;
+
diff --git a/menubar.c b/menubar.c
new file mode 100644
index 0000000..ec059b3
--- /dev/null
+++ b/menubar.c
@@ -0,0 +1,228 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+#include <stdbool.h>
+#include <ncurses.h>
+#include <string.h>
+
+#include "commands.h"
+#include "menubar.h"
+
+/* menu colors */
+#define MENU_ATT_NORMAL 0x07
+#define MENU_ATT_SEL 0xF1
+#define MENU_ATT_ACCEL_NORMAL 0x17
+#define MENU_ATT_ACCEL_SEL 0xE1
+
+#define MAX_ITEMS_PER_MENU 32
+
+typedef struct MenuItem_ {
+ char accel; /* accelerator (shortcut) char */
+ const char *caption; /* text of the item. If text is "", it is a separator
+ * In that case all remaining fields have no meaning */
+ int command; /* the command that this item triggers when
+ * selected - this value will be returned by
+ * menubar_show */
+ const char *desc; /* description of the item, which will appear at
+ * the bottom part of the screen when the item
+ * is highlighted */
+} MenuItem;
+
+typedef struct Menu_ {
+ const char *caption; /* text */
+ int startcol; /* column at which the left edge of this menu is
+ * placed onscreen */
+ int menu_h, menu_w; /* menu dimensions. If 0, calculated at run-time */
+
+ int item_count; /* how many items this menu has */
+ MenuItem item[MAX_ITEMS_PER_MENU]; /* vector of items */
+
+} Menu;
+
+/* menu data (included as a separate file for better organization) */
+#include "menubar-items.inc"
+/* defines menu[] as an array of menu's, and menu_count. */
+
+/* menu state */
+static int open_menu; /* which menu is open */
+static int menu_sel; /* which item is currently selected on the
+ * currently open menu */
+
+/* declaration of internal functions */
+static void menubar_paint(); /* paints menu onscreen */
+static void menuitem_print(const char *caption, bool sel, int minlen);
+static void menu_calc_dims(Menu *m);
+static bool chr_icomp(char c1, char c2); /* compares characters,
+ * case-insensitive */
+
+int menubar_show(int startm) {
+ int ch, i;
+ int cmd = 0; bool quit = false;
+ Menu *omenu;
+ menu_sel = 0;
+
+ open_menu = startm;
+ if (open_menu < 0) open_menu = 0;
+ if (open_menu >= menu_count) open_menu = menu_count - 1;
+
+ push_screen();
+
+ while (!quit) {
+ omenu = &menu[open_menu];
+ menubar_paint();
+ ch = getch();
+
+ switch (ch) {
+ case KEY_LEFT: if (--open_menu < 0) open_menu = menu_count-1;
+ menu_sel = 0;
+ break;
+ case KEY_RIGHT: if (++open_menu >= menu_count) open_menu = 0;
+ menu_sel = 0;
+ break;
+ case KEY_UP:
+ do {
+ if (--menu_sel < 0) menu_sel = omenu->item_count-1;
+ } while (!*(omenu->item[menu_sel].caption));
+ break;
+ case KEY_DOWN:
+ do {
+ if (++menu_sel >= omenu->item_count) menu_sel = 0;
+ } while (!*(omenu->item[menu_sel].caption));
+ break;
+ case 10: quit = true; cmd = omenu->item[menu_sel].command;
+ break;
+ case 27: quit = true; cmd = COMMAND_UNDEFINED;
+ break;
+ }
+
+ if (ch > KEY_F0 && ch <= KEY_F(12) && (ch - KEY_F0 - 1) < menu_count) {
+ open_menu = ch - KEY_F0 - 1;
+ menu_sel = 0;
+ }
+
+ /* handle accelerator keys */
+ for (i = 0; i < omenu->item_count; i++) {
+ if (chr_icomp(omenu->item[i].accel, ch)) {
+ /* item selected by accelerator key */
+ cmd = omenu->item[i].command;
+ quit = true;
+ break;
+ }
+ }
+ }
+
+ restore_screen();
+ pop_screen();
+ refresh();
+ return cmd;
+}
+
+static bool chr_icomp(char c1, char c2) {
+ c1 = (c1 >= 'A' && c1 <= 'Z') ? c1 - 'A' + 'a' : c1;
+ c2 = (c2 >= 'A' && c2 <= 'Z') ? c2 - 'A' + 'a' : c2;
+ return (c1 == c2);
+}
+
+static void menubar_paint() {
+ int i;
+ Menu *omenu;
+ restore_screen();
+ /* paint the bar at the top of the screen */
+ kurses_color_at(MENU_ATT_NORMAL);
+ draw_hline(0, 0, kurses_width(), ' ', ' ', ' ');
+
+ for (i = 0; i < menu_count; i++) {
+ kurses_move(menu[i].startcol, 0);
+ menuitem_print(menu[i].caption, i == open_menu, -1);
+ }
+
+ omenu = &menu[open_menu];
+
+ /* if open menu's dimensions have not yet been calculated, do so */
+ if (!omenu->menu_h) menu_calc_dims(omenu);
+
+ /* paint the open menu */
+ kurses_color_at(MENU_ATT_NORMAL);
+ draw_window(omenu->startcol, 1, omenu->menu_w + 2, omenu->menu_h + 2, "");
+ for (i = 0; i < omenu->item_count; i++) {
+ kurses_move(omenu->startcol+1, i + 2);
+ menuitem_print(omenu->item[i].caption, i == menu_sel, omenu->menu_w);
+ }
+
+ /* paint the description line */
+ kurses_move(0, kurses_height()-1);
+ kurses_color_at(MENU_ATT_NORMAL);
+ i = strlen(omenu->item[menu_sel].desc);
+ addstr(omenu->item[menu_sel].desc);
+ while (i++ < kurses_width()) addch(' ');
+
+ kurses_move(kurses_width()-1, kurses_height()-1);
+ refresh();
+}
+
+static void menuitem_print(const char *s, bool sel, int minlen) {
+ bool next_is_accel = false;
+ int printed = 0;
+ while (*s || (printed < minlen)) {
+ if (*s == '&') {
+ next_is_accel = true;
+ s++;
+ continue;
+ }
+
+ kurses_color_at(sel ?
+ ( next_is_accel ? MENU_ATT_ACCEL_SEL : MENU_ATT_SEL ) :
+ ( next_is_accel ? MENU_ATT_ACCEL_NORMAL : MENU_ATT_NORMAL ));
+
+ addch(*s ? *s : ' ');
+ printed++;
+
+ next_is_accel = false;
+ if (*s) s++;
+ }
+}
+
+static void menu_calc_dims(Menu *m) {
+ int i;
+ int width = 1, len = 0;
+
+ for (i = 0; i < m->item_count; i++) {
+ len = strlen(m->item[i].caption);
+ if (len > width) width = len;
+ }
+
+ m->menu_h = m->item_count;
+ m->menu_w = width;
+}
+
diff --git a/menubar.h b/menubar.h
new file mode 100644
index 0000000..64e924c
--- /dev/null
+++ b/menubar.h
@@ -0,0 +1,51 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewan_menubar_h
+#define _btco_aewan_menubar_h
+
+/* Shows the menu onscreen and lets the user interact with it.
+ * Returns the command number (as in command.h) of the selected item.
+ * This function will restore the screen contents to their previous
+ * state before returning (a most unusual courtesy, mind you).
+ *
+ * If the user cancels the menu, returns COMMAND_UNDEFINED.
+ *
+ * startopen gives the index of the menu that should be rolled down
+ * by default. If 0, the leftmost menu will start rolled down; if 1,
+ * the next one to the right will and so on.
+ */
+int menubar_show(int startopen);
+
+#endif
+
diff --git a/psd.c b/psd.c
new file mode 100644
index 0000000..a80ca93
--- /dev/null
+++ b/psd.c
@@ -0,0 +1,82 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+
+#include "psd.h"
+#include "document.h"
+
+/* global program state data definitions */
+struct _Document *_doc;
+char *_filename;
+int _lyr;
+int _x, _y;
+int _svx, _svy;
+int _fg, _bg;
+int _selmode;
+int _ax, _ay;
+bool _insmode;
+bool _lgmode;
+bool _compmode;
+struct _Layer *_clipboard;
+
+
+void get_norm_sel(int *x0, int *y0, int *x1, int *y1) {
+ sort_two(_x, _ax, x0, x1);
+ sort_two(_y, _ay, y0, y1);
+}
+
+bool doc_empty() { return 0 >= _doc->layer_count; }
+
+void zero_state() {
+ _doc = document_create();
+ _filename = 0;
+ _lyr = _x = _y = _svx = _svy = _ax = _ay = 0;
+ _selmode = SM_NONE;
+ _fg = 7;
+ _bg = 0;
+ _insmode = false;
+ _clipboard = 0;
+ _lgmode = false;
+ _compmode = false;
+}
+
+void switch_to_layer(int l) {
+ Layer *lyr;
+ if (l < 0 || l >= _doc->layer_count) return;
+
+ lyr = _doc->layers[_lyr = l];
+ if (_x >= lyr->width) _x = lyr->width - 1;
+ if (_y >= lyr->height) _y = lyr->height - 1;
+}
+
diff --git a/psd.h b/psd.h
new file mode 100644
index 0000000..a270441
--- /dev/null
+++ b/psd.h
@@ -0,0 +1,98 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_psd_h
+#define _btco_aewan_psd_h
+
+#include "bores/bores.h"
+
+#include "version.h"
+
+/* selection modes: */
+#define SM_NONE 0 /* no selection */
+#define SM_SELECT 1 /* grow/shrink selection box */
+#define SM_FLOAT 2 /* paste mode: clipboard floats around screen */
+
+struct _Document;
+
+/* global program state data declarations */
+extern struct _Document *_doc;
+ /* the current document. Must ALWAYS be non-null. */
+
+extern char *_filename; /* the name of the file from which it was loaded;
+ * NULL if new file */
+
+extern int _lyr; /* currently active layer. This is a valid layer
+ * index if and only if _doc->layer_count >= 1 */
+extern int _x, _y; /* cursor position (logical coordinates) */
+extern int _svx, _svy;/* "smallest visible x" and "smallest visible y"
+ * These are used in order to convert logical coordinates
+ * to screen coordinates. Logical coordinates _svx,_svy
+ * are mapped to screen (0,0). */
+extern int _fg, _bg; /* currently selected foreground and background colors */
+extern int _selmode; /* selection mode: SM_NONE, SM_SELECT, SM_FLOAT */
+extern int _ax, _ay; /* the anchor-point (i.e. where the selection begins).
+ * Valid only if _selmode == true */
+extern bool _insmode;/* whether insert mode is on. In insert mode, typing
+ * a character on a line shifts the other characters
+ * to the right. */
+
+extern bool _lgmode; /* line graphics mode. When this mode is active,
+ certain keystrokes produce different characters */
+
+extern bool _compmode; /* composite mode. In this mode, all layers will
+ * be visible. */
+
+extern struct _Layer *_clipboard;
+ /* clipboard layer. NULL if nothing in clipboard. */
+
+/* --- functions that operate on psd ------------------------------------- */
+
+/* Zeroes program state data */
+void zero_state(void);
+
+/* Convenience function that returns whether document is empty or not */
+bool doc_empty(void);
+
+/* Obtains normalized selection coordinates. Returned coordinates x0, y0,
+ * x1, y1 represent the selection rectangle, with the property that
+ * x0 <= x1 and y0 <= y1 */
+void get_norm_sel(int *x0, int *y0, int *x1, int *y1);
+
+/* Switches active layer to l. Does appropriate coordinate bound
+ * checking and other administrative tasks */
+void switch_to_layer(int l);
+
+#endif
+
diff --git a/python/NOTICE b/python/NOTICE
new file mode 100644
index 0000000..f5e4b00
--- /dev/null
+++ b/python/NOTICE
@@ -0,0 +1,6 @@
+The python module for loading AES files is
+out of date, since the AES format is now
+obsolete.
+
+Hey, maybe YOU could code it!
+
diff --git a/python/aewan.py b/python/aewan.py
new file mode 100644
index 0000000..e5a9962
--- /dev/null
+++ b/python/aewan.py
@@ -0,0 +1,185 @@
+# Copyright (c) 2004 Bruno T. C. de Oliveira
+#
+# LICENSE INFORMATION:
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Copyright (c) 2002 Bruno T. C. de Oliveira
+#
+# INFORMAÇÕES DE LICENÇA:
+# Este programa é um software de livre distribuição; você pode
+# redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+# Public License, conforme publicado pela Free Software Foundation,
+# pela versão 2 da licença ou qualquer versão posterior.
+#
+# Este programa é distribuído na esperança de que ele será útil
+# aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+# a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+# QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+# License para obter mais detalhes (uma cópia acompanha este
+# programa, armazenada no arquivo COPYING).
+
+import sys, os, string
+import gzip
+import curses
+
+class AeError(Exception):
+ def __init__(self, arg):
+ Exception.__init__(self, arg)
+
+class AeDoc:
+ """
+ Represents an aewan document loaded from a file.
+ Attributes:
+
+ layers[] - list of layers (AeLayer objects)
+ """
+ def __init__(self, file):
+ """
+ Creates a new aewan document object by loading it from the
+ specified file. The file must be in AES format, as generated
+ by the ae2aes conversion utility. The file may be gzip-compressed.
+
+ If there is a format-related error while loading the document,
+ raises an AeError. If there is an I/O related error, raises an IOError.
+ """
+ self.layers = []
+
+ f = gzip.open(file, 'r')
+ _read_marker(f, "AES v1.0")
+ _read_marker(f, "begin document")
+
+ layercount = _read_field_int(f, "layer-count")
+ for i in range(layercount):
+ self.layers.append(AeLayer(f))
+
+ _read_marker(f, "end document")
+
+
+class AeLayer:
+ """
+ Represents each of the layers in an aewan document. Attributes:
+
+ name
+ width
+ height
+ visible - 1 if layer is marked as visible, 0 otherwise
+ transparent - 1 if layer is marked as transparent, 0 otherwise
+
+ char[height][width] - the character at each position in the layer
+ attr[height][width] - the attribute of each position in the layer
+
+ Please note that the char and attr matrices are addressed
+ with indexes [y][x], NOT the more intuitive [x][y].
+ """
+ def __init__(self, f):
+ """
+ Initializes a new layer by loading its data from file object f.
+ Raises an AeError if a format-related error occurs, or an IOError
+ if an i/o-related error occurs.
+ """
+ _read_marker(f, "begin layer")
+ self.name = _read_field(f, "name")
+ self.width = _read_field_int(f, "width")
+ self.height = _read_field_int(f, "height")
+ self.visible = _read_field_int(f, "visible")
+ self.transparent = _read_field_int(f, "transparent")
+ _read_marker(f, "begin canvas")
+
+ self.char = []
+ self.attr = []
+ for y in range(self.height):
+ a = string.split(string.strip(f.readline()))
+ if len(a) != self.width * 2:
+ raise AeError("Canvas line with insufficient cells:\n" + a)
+
+ char_row = []
+ attr_row = []
+ for x in range(self.width):
+ try:
+ char_row.append(int(a[x * 2], 16))
+ attr_row.append(int(a[x * 2 + 1], 16))
+ except ValueError:
+ raise AeError("Error: map cell x=%d, y=%d has invalid data\n"
+ "(not a hexadecimal number)" % (x,y))
+
+ self.char.append(char_row)
+ self.attr.append(attr_row)
+
+ _read_marker(f, "end canvas")
+ _read_marker(f, "end layer")
+
+ def render(self, wnd, dest_x, dest_y, dest_w, dest_h, src_x, src_y, \
+ setattr_cb):
+ """
+ Render the contents of this layer using curses. The image will
+ be rendered on the curses window identified by wnd, and will
+ be confined to the rectangle defined by the dest_* arguments.
+ The image will be translated in such a way that the left-top
+ corner of the destination rectangle will show the layer cell
+ whose coordinates are src_x, src_y.
+
+ In order to set curses attributes for each cell, this function
+ will call setattr_cb passing it the window and the attribute as
+ parameters.
+ """
+ for y in range(dest_h):
+ wnd.move(y + dest_y, dest_x)
+ for x in range(dest_w):
+ sx = x + src_x
+ sy = y + src_y
+ if 0 <= sx < self.width and 0 <= sy < self.height:
+ ch = self.char[sy][sx]
+ if 0 <= ch < 32: ch = 32 # don't display control chars
+ # FIXME: this doesn't display special line-graphics
+ # characters. Ideally, we should convert special
+ # characters into the appropriate ACS_* characters
+ # at this point.
+
+ at = self.attr[sy][sx]
+ else:
+ ch = 0x20
+ at = 0x70
+
+ setattr_cb(wnd, at)
+ wnd.addch(chr(ch))
+
+
+# ------------------------------------------------------------------------
+def _read_marker(f, str):
+ line = string.strip(f.readline())
+ if line == str: return
+ raise AeError("Incorrectly formatted AES document.\n"
+ "Expected marker: '%s'\nBut found: '%s'\n" % (str,line))
+
+def _read_field(f, fieldname):
+ line = string.strip(f.readline())
+ a = string.split(line, maxsplit=1)
+
+ if len(a) != 2:
+ raise AeError("Incorrect field syntax in AES document:\n%s\n" % line)
+
+ if a[0] != fieldname:
+ raise AeError("AES field name mismatch.\nExpected: '%s'\nFound: '%s'" \
+ % (fieldname, a[0]))
+
+ return a[1]
+
+def _read_field_int(f, fieldname):
+ x = _read_field(f, fieldname);
+ try:
+ return int(x)
+ except ValueError:
+ raise AeError("AES field type mismatch: expected an integer\n"
+ "Field name: '%s'\nValue: '%s'" % (fieldname, x))
+
diff --git a/python/test.py b/python/test.py
new file mode 100644
index 0000000..a7f618d
--- /dev/null
+++ b/python/test.py
@@ -0,0 +1,54 @@
+from aewan import AeDoc, AeLayer
+import curses
+import sys
+
+def setattr(wnd, at):
+ at = int(at)
+ fg = at >> 4
+ bg = at & 0x0f
+ bold = 0
+ blink = 0
+
+ if fg > 7:
+ bold = 1
+ fg = fg - 8
+
+ if bg > 7:
+ blink = 1
+ bg = bg - 8
+
+ if fg == 7 and bg == 0: wnd.attrset(curses.A_NORMAL)
+ elif fg == 0 and bg == 0: wnd.attrset(curses.color_pair(7))
+ else: wnd.attrset(curses.color_pair(bg * 8 + fg))
+
+ if bold: wnd.attron(curses.A_BOLD)
+ if blink: wnd.attron(curses.A_BLINK)
+
+stdscr = curses.initscr()
+curses.noecho()
+curses.start_color()
+
+for bg in range(8):
+ for fg in range(8):
+ if bg > 0 or fg > 0: curses.init_pair(bg*8 + fg, fg, bg)
+
+curses.init_pair(7, 0, 0)
+
+
+stdscr.clear()
+
+d = AeDoc("/tmp/ut.aes.gz")
+
+sx = sy = 0
+while 1:
+ d.layers[0].render(stdscr, 20, 8, 40, 10, sx, sy, setattr)
+ stdscr.refresh()
+ ch = chr(stdscr.getch())
+ if ch == 'h': sx = sx - 1
+ elif ch == 'l': sx = sx + 1
+ elif ch == 'k': sy = sy - 1
+ elif ch == 'j': sy = sy + 1
+ elif ch == 'q':
+ curses.endwin()
+ sys.exit(0)
+
diff --git a/ui.c b/ui.c
new file mode 100644
index 0000000..842571e
--- /dev/null
+++ b/ui.c
@@ -0,0 +1,141 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+#include <ncurses.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ui.h"
+
+int ui_cancel; /* global cancel flag */
+
+/* clears bottom line of screen and puts cursor at the beginning of that line.
+ * Also lowers the global ui_cancel flag. */
+static void ui_prepare_ex(int fg, int bg) {
+ int w = kurses_width();
+ kurses_move(0, kurses_height() - 1);
+ kurses_color(fg, bg);
+ while (w--) addch(' ');
+ kurses_move(0, kurses_height() - 1);
+ ui_cancel = 0;
+}
+
+static void ui_prepare(void) {
+ ui_prepare_ex(15, 4);
+}
+
+
+int ui_ask_i(const char *prompt, int def, int min, int max) {
+ static char buf[32]; int ans;
+
+ do {
+ ui_prepare();
+ printw("%s [%d]: ", prompt, def);
+ if (!kurses_line_input(buf, 32)) return (ui_cancel = -1);
+ if (!*buf) return def; /* user just pressed ENTER, so use default */
+ ans = atoi(buf);
+ } while (!(ans >= min && ans <= max));
+
+ return ans;
+}
+
+char *ui_ask_s(const char *prompt, const char *def) {
+ static char buf[256];
+ ui_prepare();
+
+ if (def) printw("%s [%s]: ", prompt, def);
+ else printw("%s: ", prompt);
+
+ if (!kurses_line_input(buf, 256)) { ui_cancel = -1; return NULL; }
+
+ /* if user didn't type anything and there is a default, return default;
+ * otherwise just return whatever it is the user typed (even if it's an
+ * empty string) */
+ if (!*buf && def) return strdup(def);
+ else return strdup(buf);
+}
+
+int ui_ask_color(const char *prompt) {
+ int i;
+ static char hexdigit[] = "0123456789abcdef";
+ ui_prepare();
+ printw("%s ", prompt);
+
+ /* print the colors */
+ for (i = 0; i <= 15; i++) {
+ kurses_color(i, i ? 0 : 7);
+ printw(" %c ", hexdigit[i]);
+ }
+
+ kurses_color(0, 7);
+ printw(": ");
+
+ while (1) {
+ int ch, color_code;
+ ch = getch(); color_code = (ch >= 'a' && ch <= 'f') ? ch - 'a' + 10 :
+ (ch >= 'A' && ch <= 'F') ? ch - 'A' + 10 :
+ ch - '0';
+ if (ch == 27 || ch == 3 || ch == 7) return (ui_cancel = -1);
+ if (color_code >= 0 && color_code <= 15) return color_code;
+ }
+}
+
+int ui_ask_yn(const char *prompt, int defyes) {
+ ui_prepare();
+ printw("%s [%s] ", prompt, defyes ? "Yes" : "No");
+ while (1) {
+ int ch = getch();
+ switch (ch) {
+ case 10: return defyes;
+
+ case 'y': case 'Y': return 1;
+ case 'n': case 'N': return 0;
+
+ case 27:
+ case 3:
+ case 7: return (ui_cancel = -1);
+ }
+ }
+}
+
+void ui_message(const char *msg, int error) {
+ if (error)
+ ui_prepare_ex(15, 1);
+ else
+ ui_prepare();
+
+ addstr(msg);
+ getch();
+}
+
diff --git a/ui.h b/ui.h
new file mode 100644
index 0000000..7debdb1
--- /dev/null
+++ b/ui.h
@@ -0,0 +1,80 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+
+#ifndef _btco_aewan_ui_h
+#define _btco_aewan_ui_h
+
+#include <stdbool.h>
+#include "bores/bores.h"
+
+extern int ui_cancel; /* raised if the user cancels input in any of the
+ * ui_* functions. */
+
+/* Asks the user to input an integer number. Presents the given prompt.
+ * If the user just presses ENTER, returns <def>. Otherwise, returns
+ * the user's input if min <= input <= max. If the user input is not
+ * in the [min,max] interval, keeps asking again until the user inputs
+ * a valid value. If the user presses ESC, or Ctrl+C or any such thing,
+ * the return value is undefined and the global flag ui_cancel is raised.
+ * The ui_cancel flag is lowered at the beginning of the operation, so
+ * there is no need to lower it before calling this function. */
+int ui_ask_i(const char *prompt, int def, int min, int max);
+
+/* Asks the user to input a string. Behavior is similar to ui_ask_i.
+ * The returned string is dynamically allocated and should be free()'d
+ * by the caller. Even if the default value is returned, the return value
+ * is an strdup()'ed value, so it should be free()'d by caller even in
+ * that case. */
+char *ui_ask_s(const char *prompt, const char *def);
+
+/* Asks the user a color. Similar to the other ui_ask_ functions.
+ * Returns the selected color code, between 0 and 15 inclusive. */
+int ui_ask_color(const char *prompt);
+
+/* Asks a yes/no question. If <defyes>, the default is yes, otherwise
+ * the default is no. Returns whether the user chose yes or not.
+ * If the user cancels, ui_cancel is set to true and return value
+ * is undefined. */
+int ui_ask_yn(const char *prompt, int defyes);
+
+/* Presents a message to the user and awaits for a keypress.
+ * If <level> is UIMSG_ERROR, message will be shown as an error condition
+ * (i.e. in red and possibly accompanied by a beep). */
+void ui_message(const char *msg, int level);
+ #define UIMSG_INFORM 0
+ #define UIMSG_ERROR 1
+
+
+#endif
+
diff --git a/version.h b/version.h
new file mode 100644
index 0000000..ecb252a
--- /dev/null
+++ b/version.h
@@ -0,0 +1,41 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewan_version_h
+#define _btco_aewan_version_h
+
+#define AEWAN_PROGRAM_VERSION "1.0.01"
+#define AEWAN_PROGRAM_VERSION_NAME "novae"
+
+#endif
+
diff --git a/vlayer.c b/vlayer.c
new file mode 100644
index 0000000..02689d2
--- /dev/null
+++ b/vlayer.c
@@ -0,0 +1,48 @@
+#include "bores/bores.h"
+#include "vlayer.h"
+
+/* callback that returns a cell from a given layer */
+static void _get_cell_LYR(Cell *r_cell, int x, int y, void *ud) {
+ Layer *l = (Layer*) ud;
+ *r_cell = l->cells[x][y];
+}
+
+/* callback that returns a cell from a document composite */
+static void _get_cell_COMPOSITE(Cell *r_cell, int x, int y, void *ud) {
+ Document *doc = (Document*) doc;
+ *r_cell = document_calc_effective_cell(doc, x, y);
+}
+
+VirtualLayer *vlayer_create(int width, int height, vlayer_get_cell_t get_cell,
+ void *user_data){
+ VirtualLayer *vl = zalloc(sizeof(VirtualLayer));
+ vl->width = width;
+ vl->height = height;
+ vl->get_cell = get_cell;
+ vl->user_data = user_data;
+ return vl;
+}
+
+VirtualLayer *vlayer_create_from_layer(Layer *l) {
+ return vlayer_create(l->width, l->height, _get_cell_LYR, (void*) l);
+}
+
+VirtualLayer *vlayer_create_from_composite(Document *doc) {
+ if (doc->layer_count <= 0) return NULL;
+ return vlayer_create(doc->layers[0]->width, doc->layers[0]->height,
+ _get_cell_COMPOSITE, (void*) doc);
+}
+
+void vlayer_destroy(VirtualLayer *vl) {
+ if (!vl) return;
+ sfree(vl);
+}
+
+void vlayer_get_cell(VirtualLayer *vl, Cell *r_cell, int x, int y) {
+ if (x < 0 || x >= vl->width || y < 0 || y >= vl->height) {
+ r_cell->ch = ' ';
+ r_cell->attr = 0x70;
+ }
+ else vl->get_cell(r_cell, x, y, vl->user_data);
+}
+
diff --git a/vlayer.h b/vlayer.h
new file mode 100644
index 0000000..36f6b16
--- /dev/null
+++ b/vlayer.h
@@ -0,0 +1,80 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewan_vlayer_h
+#define _btco_aewan_vlayer_h
+
+#include "document.h"
+
+typedef void (*vlayer_get_cell_t)(Cell *r_cell, int x, int y, void *ud);
+
+/* A virtual layer. A virtual layer is a structure used when one wishes
+ * to represent a layer abstractly, where a callback function is responsible
+ * for returning the content of any given cell upon request. The layer
+ * does not exist physically (or perhaps it does, but we don't know),
+ * and we only rely on the function to retrieve the virtual layer's content.
+ * It is primarily used for export and display purposes where one wishes
+ * to have a unified interface to deal with actual layers, composites
+ * and all such things that are implemented differently but have the
+ * same "outside appearance". */
+typedef struct VirtualLayer_ {
+ int width, height; /* dimensions of the virtual layer */
+ vlayer_get_cell_t get_cell; /* the callback that
+ * retrieves what is at cell (x,y) and records that
+ * in the structure pointed by r_cell */
+ void *user_data; /* arbitrary data passed as the ud parameter of get_cell */
+} VirtualLayer;
+
+/* Creates a virtual layer with the given dimensions, callback function,
+ * and user data */
+VirtualLayer *vlayer_create(int width, int height, vlayer_get_cell_t get_cell,
+ void *user_data);
+
+/* Creates a virtual layer based on the physical layer l. You MUST NOT DESTROY
+ * the layer l while the virtual layer exists. */
+VirtualLayer *vlayer_create_from_layer(Layer *l);
+
+/* Creates a virtual layer formed by making a composite from all the layers
+ * of the given document. You MUST NOT DESTROY the document while the
+ * virtual layer exists. */
+VirtualLayer *vlayer_create_from_composite(Document *doc);
+
+/* Destroys a virtual layer previously created with one of the creator
+ * functions */
+void vlayer_destroy(VirtualLayer *vl);
+
+/* Gets a cell from a virtual layer. The cell is filled in r_cell. */
+void vlayer_get_cell(VirtualLayer *vl, Cell *r_cell, int x, int y);
+
+#endif
+
diff --git a/welcomedlg.c b/welcomedlg.c
new file mode 100644
index 0000000..708f631
--- /dev/null
+++ b/welcomedlg.c
@@ -0,0 +1,130 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#include "bores/bores.h"
+#include <ncurses.h>
+
+#include "welcomedlg.h"
+#include "psd.h"
+
+#define LOGO_WIDTH 11
+#define LOGO_HEIGHT 5
+
+static char* logo[] = {
+ "79 ",
+ "|| ",
+ "46799 97979",
+ "||43|||||||",
+ "311-1231231",
+ NULL
+};
+
+static int logo_colors[LOGO_HEIGHT] = { 4, 6, 7, 6, 4 };
+
+void show_welcome_dlg(void) {
+ int x0, y0, x, y, ch, *clr;
+ char **p, *q;
+ int acschars[10] = {
+ ACS_CKBOARD, /* 0 */
+ ACS_LLCORNER, /* 1 */
+ ACS_BTEE, /* 2 */
+ ACS_LRCORNER, /* 3 */
+ ACS_LTEE, /* 4 */
+ ACS_PLUS, /* 5 */
+ ACS_RTEE, /* 6 */
+ ACS_ULCORNER, /* 7 */
+ ACS_TTEE, /* 8 */
+ ACS_URCORNER /* 9 */
+ };
+
+ kurses_color(4, 0);
+ draw_centered_window(46, 18, "Welcome to AEWAN", &x0, &y0);
+ y = y0 + 1;
+
+ /* draw logo */
+ for (p = logo, clr = logo_colors; *p; p++, clr++) {
+ kurses_color(*clr, 0);
+ kurses_move(x0, y++);
+ for (q = *p; *q; q++) {
+ if (*q >= '0' && *q <= '9') ch = acschars[*q - '0'];
+ else if (*q == '-') ch = ACS_HLINE;
+ else if (*q == '|') ch = ACS_VLINE;
+ else ch = ' ';
+ addch(ch);
+ }
+ }
+
+ /* draw program name next to logo */
+ x = x0 + LOGO_WIDTH + 2;
+ y = y0 + 1;
+
+ kurses_move(x, y++);
+ kurses_color(4+8, 0);
+ addstr("AEWAN ascii art editor");
+
+ kurses_move(x, y++);
+ kurses_color(7, 0);
+ addstr("Copyright (c) 2003");
+
+ kurses_move(x, y++);
+ addstr("Bruno T. C. de Oliveira");
+
+ kurses_move(x, y++);
+ addstr("All rights reserved.");
+
+ y+=2; x = x0 + 1;
+ kurses_move(x, y++);
+ kurses_color(4+8, 0);
+ addstr("Program version: ");
+ kurses_color(7, 0);
+ addstr(AEWAN_PROGRAM_VERSION " (" AEWAN_PROGRAM_VERSION_NAME ")");
+
+ y++;
+ kurses_move(x, y++);
+ addstr("This program is licensed under the GNU");
+
+ kurses_move(x, y++);
+ addstr("General Public License. Please refer to");
+
+ kurses_move(x, y++);
+ addstr("the COPYING file for more information.");
+
+ y++;
+ kurses_move(x, y++);
+ addstr("Press RETURN to continue. When in the");
+ kurses_move(x, y++);
+ addstr("program, press <F1> to display a menu.");
+
+ getch();
+}
+
diff --git a/welcomedlg.h b/welcomedlg.h
new file mode 100644
index 0000000..c257978
--- /dev/null
+++ b/welcomedlg.h
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2003 Bruno T. C. de Oliveira
+
+LICENSE INFORMATION:
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Copyright (c) 2002 Bruno T. C. de Oliveira
+
+INFORMAÇÕES DE LICENÇA:
+Este programa é um software de livre distribuição; você pode
+redistribuí-lo e/ou modificá-lo sob os termos da GNU General
+Public License, conforme publicado pela Free Software Foundation,
+pela versão 2 da licença ou qualquer versão posterior.
+
+Este programa é distribuído na esperança de que ele será útil
+aos seus usuários, porém, SEM QUAISQUER GARANTIAS; sem sequer
+a garantia implícita de COMERCIABILIDADE ou DE ADEQUAÇÃO A
+QUALQUER FINALIDADE ESPECÍFICA. Consulte a GNU General Public
+License para obter mais detalhes (uma cópia acompanha este
+programa, armazenada no arquivo COPYING).
+*/
+
+#ifndef _btco_aewan_welcomedlg_h
+#define _btco_aewan_welcomedlg_h
+
+/* invokes the welcome dialog, that shows the program name, version,
+ * copyright information and such. Does not restore screen. */
+void show_welcome_dlg(void);
+
+#endif
+