1. Amulet V2.0 Overview

This section provides an overview of Amulet, and contains retrieval
and installation instructions.

1.1 Introduction

The Amulet research project in the School of Computer Science at
Carnegie Mellon University is creating a comprehensive set of tools
which make it significantly easier to create graphical,
highly-interactive user interfaces.  The lower levels of Amulet are
called the `Amulet Toolkit,' and these provide mechanisms that allow
programmers to code user interfaces much more easily.  Amulet stands
for Automatic Manufacture of Usable and Learnable Editors and
Toolkits.

This manual describes version 2.0 of Amulet.

Section1.9 describes the differences between Amulet v2 and previous
versions of Amulet.  Code written for Amulet v1 will need to be
editied before it will compile and run properly with Amulet v2.

The Amulet Toolkit is a portable toolkit designed for the creation of
2D direct manipulation grapical user interfaces.  It is written in C++
and can be used with Unix systems running X Windows, PC's running
Microsoft Windows NT or `95, or Macintosh systems running MacOS.

Amulet has been sucessfully installed on several platforms.  Some of
these are at CMU, and some installations are at other users' sites:

   Unix:

 OS: SunOS, HP/UX, Linux, IBM AIX, SGI

 Compilers: gcc 2.6.3, gcc 2.7.0, ObjectCenter 2.1.0, AIX xlc, SGI CC

   PC

 OS: Windows NT 3.5 and 3.51 and Windows 95

 Compilers: Visual C++ 2.0, 2.1 or 4.0

   Mac

 Compilers: Metrowerks CodeWarrior 8

We are running SunOS, HP/UX, Windows NT 3.51, and Codewarrior 8, so
we'll be best able to help you if you're using one of these systems.

We have found that most users who try to use a vendor specific C++
compiler on a Unix workstation (for example, SGI's CC) run into too
many language inconsistencies to successfully build Amulet.  We will
do what we can to help you install Amulet, but sometimes it's easier
to install a new compiler (gcc is free) than to try to get Amulet to
work on a native compiler.

There is a known bug in the gcc 2.5.8 compiler involving premature
destruction of local variables that prevents it from being able to
compile Amulet.

Amulet provides support for color and gray-scale displays.  Amulet
runs on X/11 R4 through R6, using any window manager such as mwm, uwm,
twm, etc.  It does not use any X toolkit (such as Xtk or TCL).  It has
been implemented using the native Windows graphics system on the PC,
and standard QuickDraw on the Macintosh.  Because of stack-size
limitations on the 16-bit Windows operating system, Amulet requires PC
users to run Windows NT or Windows 95.

More details about Amulet are available in the Amulet home page on the
World Wide Web:

http://www.cs.cmu.edu/~amulet

A previous project named Garnet was developed by the same group who is
now writing Amulet.  It has features similar to those in Amulet, but
is implemented in Lisp.  For information about Garnet, please refer to
the Garnet home page:

http://www.cs.cmu.edu/~garnet

1.2 Amulet Email Addresses

There is a mailing list called amulet-users@cs.cmu.edu where users and
developers exchange information about Amulet.  Topics include user
questions and software releases.  To be added to the list, please send
your request to amulet-users-request@cs.cmu.edu.

Please send questions about installing Amulet to amulet@cs.cmu.edu.

You can also send bug reports directly to amulet-bugs@cs.cmu.edu.
This mail is read only by the Amulet developers.

Another mailing list, amulet-interest@cs.cmu.edu, is available for
people who are interested in learning only about new releases of
Amulet.

1.3 Using Amulet in Products: Copyright and Licensing

Amulet is available for free by anonymous FTP or WWW.  Amulet has been
put into the public domain.  This means that anyone can use Amulet for
whatever they want.  In particular, Amulet can be used for commercial
development without any license or fees.  The resulting binaries and
libraries can also be distributed commercially or for free without
payments or licenses to Carnegie Mellon University (CMU).  You can
even include portions of the Amulet source code in your projects or
products.  The only restriction is that the documentation for Amulet
is copyrighted, so you cannot distribute the Amulet manual or papers
without permission from CMU.  In return, CMU assumes no responsibility
for how well Amulet works, and will not guarantee to provide any
support.  If you need more formal legal language, see Section1.10
below.  If you need this formally signed, then replace your company's
name for COMPANY and send it back to us.

Of course, the Amulet research group would appreciate any corporate
grants or donations to support the further development and maintenance
of Amulet.  We would also be interested in discussing grants to
support adding specific features to the system that would make it more
useful for your needs.  Please contact Brad Myers at bam@cs.cmu.edu to
discuss this.

If you decide to use Amulet, we would like to be able to mention this
in our publicity and reports to our sponsors.  (We get recognition for
having users, both commercial and research projects.)  Please send
mail to amulet@cs.cmu.edu with the name of your project or product.
We also like to receive screenshots.  If you write papers or
advertizements about systems built with Amulet, we would appreciate if
you included a mention that you used Amulet, and a reference to this
manual, and we would like a copy of your paper for our files.

For complete license and legal information, please see Section1.10.

1.4 How to Retrieve and Install Amulet

You will download a different file depending on whether you're
installing Amulet on a Unix, PC, or Macintosh system.  You will get
only the files you need to compile Amulet on your machine.  If you
plan to install Amulet on multiple platform types, you will need to
download a different distribution for each platform type.

These instructions assume that a C++ compiler such as gcc, CC, or
Visual C++ has been installed properly on your system, and you know
the location of your window manager libraries, etc.  Amulet will not
compile with gcc 2.5.8.

1.4.1 The Amulet Manual

The Amulet documentation is also available for free, but it is
copyrighted.  This means you cannot distribute the Amulet manuals
without written permission from the authors.

The Amulet manual is distributed separately from the Amulet source
code.  It is available in postscript format, either uncompressed, or
compressed with compress (for UNIX) or pkzip (for the PC).  The amulet
manual is also available online.  The table of contents is at:

http://www.cs.cmu.edu/afs/cs/project/amulet/amulet2/manual/Amulet_ManualTOC.doc.html

To retrieve the Amulet documentation via WWW, launch your favorite
browser and go to the following URL:

http://www.cs.cmu.edu/~amulet/amulet2-documentation.html

Follow the instructions on that web page to download a copy of the
Amulet manual.

To download the Amulet manual using FTP, connect to ftp.cs.cmu.edu
(128.2.206.173) and login as "anonymous" with your e-mail address as
the password.  Type 'cd /usr0/anon/project/amulet/amulet2' (note the
double amulet's).  Do not type a trailing "/" in the directory name,
and do not try to change directories in multiple steps, since the
intermediate directories are probably protected from anonymous access.

Set the mode of your FTP connection to binary: Some versions of FTP
require you to type 'binary' at the prompt, and others require
something like 'set mode binary'.

At the "ftp>" prompt, get the manual file you require using the get
command: "ammanual.ps" is raw postscript, "ammanual.zip" is PC zip
format, and "ammanual.Z" is UNIX compress format.

1.4.2 Retreiving the Amulet source code distribution

The Amulet source distribution can be retrieved via anonymous FTP, or
from the Amulet WWW pages.

1.4.2.1 Retrieving the source distribution via FTP

To download the compressed Amulet source code files via FTP, you'll
need an FTP client program.  FTP to ftp.cs.cmu.edu (128.2.206.173) and
login as 'anonymous' with your e-mail address as the password.

Type 'cd /usr0/anon/project/amulet/amulet2'.  Do not type a trailing
'/' in the name of the directory, and do not try to change directories
in multiple steps, since the intermediate directories are probably
protected from anonymous access.

Set the mode of your FTP connection to binary: Some versions of FTP
require you to type 'binary' at the prompt, and others require
something like 'set mode binary'.

At the "ftp>" prompt, type "get" followed by the name of the source
distribution you require.  The UNIX version of Amulet is called
"amulet.tar.Z", the PC version is called "amulet.zip",and the
Macintosh version is called "amulet.sea.hqx".  For example, if you
wanted the UNIX version, you'd type "get amulet.tar.Z" and press
return.

1.4.2.2 Retrieving the source distribution via WWW

To download the compressed Amulet source code files from the WWW
you'll need a web browser such as Netscape, Mosaic, lynx, or www.  Run
your browser and go to the following URL:

http://www.cs.cmu.edu/~amulet/amulet2-release.html

Scroll down to the section of the web page labelled "Downloading the
current release of Amulet."  Follow the link appropriate for the
version of Amulet you want to download.  This will automatically
download the compressed Amulet source code to your machine.

1.4.3 Installing Amulet on a PC

To install Amulet on your PC, you will need to retrieve the file
amulet.zip as described in Section1.4.2.

1.4.3.1 Unpacking amulet.zip

Once you have retrieved the file amulet.zip via FTP or WWW, unzip it
into the directory where you want it to reside, preserving the
directory structure.  For example, if you use pkunzip and want to have
Amulet files in the C:\AMULET directory, at the DOS prompt type
'pkunzip -d amulet.zip C:\'.

It is easiest to use Amulet in the base directory \AMULET.  The
tutorial and installation instructions assume you installed amulet in
C:\AMULET.  The provided .mak and .mdp files expect to find all your
source files in that directory structure.  If you place your Amulet
directory somewhere else, you may need to change the makefiles to find
your source code elsewhere.  The easiest but most tedious way to do
this is to use Visual C++ to remove all the old files from the
project, and add all the new ones.

People familiar with PC nmake files may directly edit the .mak files
to specify the location of their files.  This is somewhat dangerous,
because changing the wrong parts of the makefile may confuse Visual
C++ and cause it to reject the file.  To manually edit the makefile,
use your favorite editor to search and replace all occurances of
C:\amulet with your preferred pathname (for example,
D:\foo\bar\amulet).  If you're using Visual C++ version 4, it might be
smart enough to find your files without as much work.

1.4.3.2 Windows Environment Variables

Next you should set the environment variable AMULET_DIR to the
directory where you installed Amulet.  In Windows NT, go to the
Program Manager, and open the Control Panel.  Choose System, and add
AMULET_DIR = C:\amulet (substitute the appropriate pathname) to the
User Environment Variables section.  Amulet uses this environment
variable to look for its dynamic link libraries, as well as some
bitmap files in the demo programs.  If the AMULET_DIR is not set,
Amulet looks in C:\amulet by default.

1.4.3.3 Configuring Visual C++

In the Visual C++ menubar, choose Tools: Options to bring up the
Visual C++ options window. Choose the Directories panel to access the
search paths.  Add the Amulet include directory C:\AMULET\INCLUDE to
the include path, and add the Amulet library directory C:\AMULET\LIB
to the library path.  (If you installed Amulet in some other
directory, be sure to specify that directory instead.)

1.4.3.4 Visual C++ Project Files

Amulet supports development with Visual C++ versions 2 and 4.  These
two development environments use different project files, so we've
provided projects for all of the sample and demo programs for both
versions of Visual C++.

Project files for use with Visual C++ version 2 have a `2' at the end
of the filename (before the extension .mak).  For example, the VC++ 2
project file that builds the Amulet library is called amulet2.mak.
Project files for Visual C++ version 4 do not have any special
characters in their names.  The VC++ version 4 project files for
building the Amulet library are amulet.mak and amulet.mdp (both are
required to build the project).  Throughout the installation
instructions, reference is made to specific .mak files. If you use
Visual C++ version 2, you should be sure to use the project file with
the `2' suffix.  Most of the project files are located in
C:\amulet\bin.  The sample projects are located in
C:\amulet\samples\*.  Be sure to use the correct project file for your
version of Visual C++.

1.4.3.5 Compiling The Amulet Library

To build any of the sample programs or to link your own application to
Amulet, you must first build the Amulet library file.  The Amulet 2.0
distribution does not come with any precompiled libraries; a different
version would be required for Visual C++ 2 or 4.

Launch the Visual C++ application, and open the Amulet library Visual
C++ project file.  This is c:\amulet\bin\amulet2.mak for Visual C++
V2, or c:\amulet\bin\amulet.mdp for Visual C++ V4.  You can do this
all in one step by double-clicking on the file from the File Manager.

The project files generate either AMULETD.LIB for a debugging version
of the Amulet library file, or AMULET.LIB for a release build.  These
two options are called targets in Visual C++ v2, and project
configurations in v4.  There is an option box in the project workspace
window which allows you to choose which of the versions you'd like to
compile.

Choose the Build All option.  Go get a cup of coffee, this'll take a
while.  Compiling Amulet may generate many warnings in Visual C++, but
there should not be any fatal errors.

Once you have a compiled version of AMULETD.LIB or AMULET.LIB, you are
ready to write your own Amulet programs and link them to the Amulet
library. Section1.4.3.6 discusses how you can build and run some of
the Amulet samples and test programs.  Your first experience with
Amulet programming should involve the Amulet Tutorial, which includes
a starter program and instructions to acquaint you with the compiling
process.  When you are ready to write your own Amulet program, see
Section1.4.3.8 for instructions about linking your new program to the
Amulet library.

1.4.3.6 Compiling Test Programs and Demos

There are about 10 test programs included in Amulet that test the
lower levels of Amulet: the ORE object system, GEM graphics routines,
OPAL graphical objects, Interactors event handlers, and Widgets.  The
project files for these tests appear in the amulet\bin\ directory. You
can build and run these programs to test your installation of Amulet,
but they are not intended to be particularly good examples of Amulet
coding style. The makefiles for these programs assume you've installed
Amulet in \AMULET, so if you want to try these programs and have
installed Amulet elsewhere, you might have to change the makefiles.

There are some other example programs in AMULET\SAMPLES\*.
Executables are provided in the PC distribution for some of the
samples.  These programs are written how you should write code as an
Amulet user, and are intended to be exemplary code.  Each of these
programs have their own .MAK file in their subdirectory, and depend on
the Amulet library file AMULET.LIB.  To generate an executable for any
of these demos, open the project file for the program, located in its
AMULET\SAMPLES\* subdirectory, and build it.  You can only compile the
samples after you have successfully compiled the Amulet library.  See
Section1.5 for descriptions of the demos, and Section1.4.3.5 for
information on compiling the Amulet library.

1.4.3.7 Using console.cpp to Simulate a Terminal Window

The Amulet test programs were designed in a Unix environment, and
require a simulated terminal window for text output.  We provide a
simple way to add a console to any of your Amulet programs, using the
file console.cpp.  To include a console in your custom Amulet program,
just add the file amulet\src\gem\console.cpp to your Visual C++
project. A console will automatically be allocated when your program
starts, and destroyed when the program completes execution.

The Microsoft Windows NT console window allows selection, cutting, and
pasting of text.  Go to the window's menu (drag off the box in its
upper left corner) to "edit," and select the submenu item "mark." This
will allow you to make a selection in the window.  Selecting the
"edit->copy" item copies the selection to the cut buffer.  If you want
the default behavior to be selection mode, go to the "Settings..."
menu item, and check off "Quick Edit."  You can also make this the
default for all future console windows by using the "Configure Default
Values" menu item.  In Quick Edit mode, the left button selects text,
and the right button copies it to the cut buffer.

The default size of an Amulet console screen buffer is 80 by 100
characters.  You can use the scroll bars in the window to look at
previous lines of text.  By changing the values of the buffer_size
structure in console.cpp and recompiling, you can change the size of
the Amulet console buffer.

1.4.3.8 Writing and Compiling New Programs Using Amulet

The easiest way to create a project file for your own Amulet program
is to copy the project file from one of the sample programs (tutorial
is a good one), remove the sample code from the project, and add your
application's .cpp files instead.  At that point you should be able to
successfully compile your Amulet application.

To start from scratch, you will need to set up your Visual C++ project
as follows:

 Create a new Visual C++ project of type Application.  You do not
need to use MFC classes in your project.

 Add your program to the project.

 If you want your program to handle terminal-style I/O, add the file
amulet\src\gem\console.cpp to your project.

 Make sure the Amulet include and library paths are set in your
Visual C++ options, as discussed in Section1.4.3.3.

 In Visual C++ 2, choose the menu item Project: Settings to bring up
your project settings.  In Visual C++ 4, choose the menu item Build:
Settings.

  In the C/C++ preprocessor settings, define NEED_BOOL and
SHORT_NAMES.  Also define _WINDOWS if it is not already defined.

  In the linker input settings, add the AMULETD.LIB library if you
want to use the 'debugging' version of the Amulet library, or
AMULET.LIB for a streamlined version.

Now you are ready to build your project.

1.4.3.9 PC filenames

To support as many users as possible, we are using 8 character file
names with 3 character extensions for the Windows Amulet files.  This
manual generally refers to Unix or machine independant file names,
which are often longer than 8 characters.  The PC files are kept in
the same directories as their equivalent Unix or Mac files.  In cases
where the Unix filenames are too long for the PC, the filename is
logically shortened, either by truncation or removal of vowels.  On
the PC, the extension .cpp is used for all C++ code files, and headers
use the extension .h.

1.4.4 Installating Amulet on a Unix Workstation

To install Amulet on your Unix workstation, you will need to retrieve
the file amulet.tar.Z as described in Section1.4.2.

1.4.4.1 Unpacking amulet.tar.Z

Expanding amulet.tar.Z into a usable Amulet directory structure is a
two part process.  At the Unix prompt, first type "uncompress
amulet.tar.Z".  Your copy of amulet.tar.Z will be replaced with
amulet.tar.  Now type "tar -xvf amulet.tar" at the Unix prompt to
generate the amulet/ directory tree as a subdirectory of your current
directory.

1.4.4.2 Setting your Environment Variables

The Amulet Makefiles have been written so that all Amulet users must
set two environment variables in their Unix shell before they can
compile any program.  Consistent binding of these variables by all
Amulet users ensures that the installed Amulet binaries will always be
compatible with user programs.  Once Amulet has been installed and
programs are being written that only depend on its library file, it
would be possible for users to write their own Makefiles without
regard to these variables.  However, we recommend that all Amulet
users at a site continue to use consistent values of environment
variables to facilitate upgrading to future versions of the
system. Typically, these environment variables will be set in your
.login file:

 AMULET_DIR Set this to the root directory of the Amulet software
hierarchy on your machine.  The csh command to do this is:

 setenv AMULET_DIR /usr/johndoe/amulet

 AMULET_VARS_FILE Set this to the Makefile.vars.* file appropriate for
your compiler and machine.  Use only the filename, not the complete
pathname to the file.  This file will be included by the main Amulet
Makefile.

If you are using SunOS or HP/UX, then set AMULET_VARS_FILE to one of
the following files, which have been tested by the Amulet group on our
own machines.

 	Makefile.vars.gcc.Sun For gcc on SunOS 4.x

 	Makefile.vars.gcc.HP For gcc on HP/UX 9.x

 	Makefile.vars.CC.Sun For ObjectCenter's CC on SunOS 4.x

 	Makefile.vars.CC.HP For ObjectCenter's CC on HP/UX 9.x

 For example, if you run csh, your .login might contain the lines

	setenv AMULET_DIR /usr/johndoe/work/amulet

	setenv AMULET_VARS_FILE Makefile.vars.CC.HP

If you are using a different platform, you may find a file tailored to
your platform in the contrib directory.  Files in contrib are provided
by other Amulet users.  Among them you will find:

 	Makefile.vars.gcc.Solaris For gcc on Solaris

 	Makefile.vars.gcc.linux For gcc on linux (static library only)

 	Makefile.vars.gcc.linux-ELF For gcc on linux with ELF shared
libraries

 	Makefile.vars.gcc.AIX For gcc on AIX

 	Makefile.vars.CC.AIX For xlc on AIX

To use one of these files, first copy it to your bin directory, so
that the Makefiles can find it, then set your AMULET_VARS_FILE
variable

If you run csh, your .login might include the lines:

		setenv AMULET_DIR /usr/janedoe/amulet

		setenv AMULET_VARS_FILE Makefile.vars.gcc.linux-ELF

If you can't find your platform in either the bin or the contrib
directory, then you should set your AMULET_VARS_FILE variable to the
file:

 	Makefile.vars.custom For any other configuration

If you run csh, your .login might include the lines:

		setenv AMULET_DIR /usr/jonwoo/amulet

		setenv AMULET_VARS_FILE Makefile.vars.custom

If you use Makefile.vars.custom, try compiling Amulet first.  If the
compilation does not finish smoothly, you probably need to make
changes to the variables in Makefile.vars.custom. See Section1.4.4.6
for more information.  Only edit amulet/bin/Makefile.vars.custom while
installing Amulet.

1.4.4.3 Generating the Amulet Library File

After you have set your environment variables, cd into the bin/
directory and invoke make, with no arguments.  This generates many
object files, and eventually the Amulet library will be deposited in
the amulet/lib/ directory.  If you are using Makefile.vars.gcc.Sun,
Makefile.vars.gcc.HP, Makefile.vars.gcc.Solaris, or
Makefile.vars.gcc.linux-ELF, then Amulet is compiled into a shared
library called libamulet.* (The suffix indicating a shared library is
platform-dependent, but it is typically .so or .sl.)  If you are using
any other compiler or platform, then Amulet is compiled into a static
library called libamulet.a.

It is common to get many warning messages during the build, but you
should have no fatal errors. If the compile procedure is interrupted
by an error, you may need to customize the Makefile variables for your
platform.  Set your AMULET_VARS_FILE environment variable to
Makefile.vars.custom, and refer to Section1.4.4.6.  Change
appropriate variables in Makefile.vars.custom, and recompile.  If you
are unable to compile Amulet after trying different combinations of
compiler switches, please send mail to amulet-bugs@cs.cmu.edu and we
will try to make the Amulet code more portable.

Once you have generated the library, you are ready to write your own
Amulet programs and link them to the Amulet library.  Your first
experience with Amulet programming should involve the Amulet Tutorial,
which includes a starter program and instructions to acquaint you with
the compiling process.  When you are ready to write your own Amulet
program, see Section1.4.4.5 for instructions on linking your new
program to the Amulet library.

1.4.4.4 Compiling Test Programs and Examples

From the bin/ directory, doing 'make all' generates about 10
executable binaries that test the lower levels of Amulet: ORE object
system, GEM graphics routines, OPAL graphical objects, Interactors
event handlers, and Widgets.  You can run these programs directly,
such as './testgem'.  You can build and run these programs to test
your installation of Amulet, but they are not intended to be
particularly good examples of Amulet coding style.

There are also some example programs in amulet/samples/*.  These
programs are more like you would write as an actual Amulet user, and
are intended to be exemplary code.  Each of these programs have their
own Makefile in their subdirectory, and depend on the Amulet library
file libamulet.a (see above).  To generate binaries for these files,
cd into their subdirectory and invoke make with no parameters.  See
Section1.5 for descriptions of these demos.

1.4.4.5 Writing and Compiling New Programs Using Amulet

It is important to set your AMULET_DIR and AMULET_VARS_FILE
environment variables, and to retain the structure of the sample
Makefiles in your local version.  By keeping the line 'include
$(AMULET_DIR)/bin/Makefile.vars' at the top of your Makefile, and
continuing to reference the Amulet Makefile variables such as
AM_CFLAGS and CC, you will be assured of generating binary files
compatible with the Amulet libraries.

When you are ready to write a new program using Amulet, it is easiest
to start with an example Makefile.  The easiest way to start a new
project is to copy the contents of samples/tutorial/ into a new
directory, and edit the Makefile and tutorial.cc files to begin your
project. Invoking make in that directory generates a binary for your
Amulet program.  The examples presented in the Amulet Tutorial all
start from this point, and can be used as models for your programs.

1.4.4.6 Customizing the Makefile.vars.custom Variables

C++ is a standardized language, but many compilers do not fully
support the ANSI standard completely or correctly.  Because of this,
Amulet requires different source code in certain places with various
platform/ compiler combinations. We handle this with conditional code
that depends on the compile-time definition of the variables defined
in your AMULET_VARS_FILE.  These variables need to be set apropriately
for your system. This section is a guide to the variables that control
the conditional Amulet code.  If, after experimenting with the
compiler variables documented below, you are still not able to
successfully compile Amulet, please send mail to
amulet-bugs@cs.cmu.edu so we can try to make the Amulet code more
portable.

Amulet will not compile in gcc 2.5.8, due to a compiler bug.

Before changing any of the Makefile variables, you should try
compiling Amulet once with one of the default Makefile.vars.* files.
If the procedure does not terminate smoothly, you should have some
indication of what switches need to be added or changed.  Make sure
that your AMULET_VARS_FILE environment variable is set to
Makefile.vars.custom (found in amulet/bin), and bring this file up in
an editor. This is the only file that you should change.

The variables that control conditional Amulet code are defined with -D
compiler switches. For example, we have found that the CC libraries on
Suns do not provide the standard function memmove(), so we have to
define it ourselves in Amulet.  The Amulet version of memmove() is
only defined when the compiler switch -DNEED_MEMMOVE is included in
the compile call (which declares the variable NEED_MEMMOVE).  By
adding or removing the -DNEED_MEMMOVE switch, you control whether
Amulet defines memmove().

The interface for defining these variables is the AM_CFLAGS list in
Makefile.vars.custom.  For each variable VAR, you would include the
switch -DVAR in the AM_CFLAGS list to define the variable, or simply
leave out the switch to avoid defining the variable.  By iteratively
adding or removing these variables from your AM_CFLAGS list and
recompiling Amulet, you should be able to install Amulet on your
system.

1.4.4.6.1 Compiler Variables

 HP Including -DHP in the AM_CFLAGS list will cause some type casting
required for HP's that is inappropriate on other machines.

 GCC Including -DGCC in the AM_CFLAGS list causes different header
files to be referenced than when Amulet is compiled with CC or Visual
C++.

 NEED_BOOL Including -DNEED_BOOL in the AM_CFLAGS list causes Amulet
to define the bool type.  This type is pre-defined in gcc.

 NEED_MEMMOVE Including -DNEED_MEMMOVE in the AM_CFLAGS list causes
Amulet to define its own memmove() function.  This function is missing
in some C libraries.

 NEED_STRING Including -DNEED_STRING in the AM_CFLAGS list causes
Amulet to include the standard header file strings.h in special places
required by some versions of the CC compiler.

 DEBUG Including -DDEBUG in the AM_OP list causes Amulet debugging
code to be compiled into your binaries.  If you do not define DEBUG,
you will lose a lot of runtime debugging information, such as slot,
object, and wrapper names, and tracing and breaking in the debugger,
but your executable will be smaller and it will run faster.  This
switch is not the same as the -g option, which compiles debugging
symbols for a debugger such as gdb into your executable.  Using the
DEBUG switch compiles in Amulet-specific runtime debugging information
which makes it easier to debug your Amulet application while it's
running.  The options -g and -DDEBUG are mutually exclusive; neither
is required to use the features the other provides.

1.4.4.6.2 Makefile Variables

 CC Your compiler, such as /usr/local/bin/gcc.

If you're compiling using ObjectCenter's CC, you may have to specify
the pathname explicitly.  Otherwise, a default (non-Centerline) CC may
be used which will not successfully compile Amulet.

 LD Your linker, such as /bin/ld.  This command is used to link
libraries into archive files.

 AM_OP Options you want to pass to your compiler, such as -g to put
gcc debugging information in the binaries, -O to enable optimization,
or -pg to enable profiling.

 AM_CFLAGS A list of switches to pass to the compiler, including the
Amulet compiler variables listed above and any include and library
paths you need to specify.

 AM_LDFLAGS A list of switches to pass to the linker.

 AM_LIBS A list of libraries to link with your program, such as -lX11
and -lg++.

 AM_LIB_SHARING A symbol indicating which kind of library should be
built: either static to make a static Amulet library (libamulet.a), or
shared to make a shared library.  This option will build shared
libraries only if your compiler is gcc, version 2.7.0 or newer.

 AM_SHLIB_SUFFIX The appropriate suffix for a shared library on your
platform.  On HP/UX, for example, shared libraries end with ".sl", but
on Solaris and linux, shared libraries end with ".so".

1.4.4.6.3 Command Line make options

Make allows you to specify override values for makefile variables on
the command line.  This allows quick testing of various Makefile
configurations without having to edit the Makefile.vars.* file every
time you want to try something new.  To override a makefile variable
on the command line, just type make <variable>=<value> <target>.  For
example, to try compiling testselectionwidget with shared libraries
turned off, type:

make AM_LIB_SHARING=static testselectionwidget

1.4.4.6.4 Xlib Pathnames

Some compilers on Unix systems do not know where to find the Xlib
library and include files.  You may need to include the pathnames for
your Xlib files in the AM_CFLAGS list in Makefile.vars.custom.  The
include path should be provided with the -I switch, and the library
path should be provided with the -L switch.

For example, some HP machines store their Xlib include and library
files in /usr/include/X11R5/ and /usr/lib/X11R5/.  If this is how your
machine is set up, your AM_CFLAGS definition would look like this:

AM_CFLAGS = -$(AM_OP) I$(AMULET_DIR)/include -DGCC -DDEBUG -DHP \

		-I/usr/include/X11R5 -L/usr/lib/X11R5

Note that a backslash is required at the end of a line when the
definition of a Makefile variable continues on the next line.

If you are having trouble finding your Xlib include and library files,
try looking in these directories:

/usr/include/X11R?, /usr/lib/X11R?

/usr/local/X11R?/include, /usr/local/X11R?/lib

1.4.4.7 Why is my application so big?

Many users complain that applications that link to the Amulet library
are very large.  It is not unusual to have a hello world program
compile down to a few megabytes of executable.  Obviously, not all of
this is useful, necessary information.  There are several things you
can do to reduce the size of your executables.

 Recompile the Amulet library and your application without the
-DDEBUG -g switches to produce your final release.  This removes
symbolic debugging information, so you can't debug the resulting
executable with a debugger such as gdb.  It also disables a lot of
code (such as the Inspector) that won't be needed in applications that
you plan to ship to a customer.

 Compile Amulet into a shared library, if your platform allows it.
Amulet is automatically compiled to shared libraries if you use gcc
2.7.0 or higher on SunOS, HP/UX, Solaris, or linux.  It may also be
possible on other compilers; consult your compiler's documentation.
Using a shared library will make all of your Amulet applications
smaller, but you must distribute all the shared libraries with your
applications and install the libraries where they can be found at
run-time.

 Run strip on your executables.  This is one of the most effective
way of shrinking your executables.  Just type "strip" followed by the
name of the program that's to large.  Strip takes out all of the
symbol tables, which are necessary at compile and link time, but are
wasted space at run time.  If you are using shared libraries, you may
also want to also strip the Amulet shared libraries before
distributing them with your application.

1.4.5 Installing Amulet on a Macintosh

To install Amulet on your Macintosh, you will need to retrieve the
file amulet.sea.hqx as described in Section1.4.2.  The Macintosh
version of Amulet is being developed with Metrowerks CodeWarrior 8.
The code will run with CodeWarrior 7 as well, but you will need to
make your own new project files (see Section1.4.5.6) for the tests
and demos.  The project files we provide will work on CodeWarrior 8,
but not on CodeWarrior 7 without modification.

1.4.5.1 Unpacking amulet.sea.hqx

Once you have retrieved the file amulet.sea.hqx via FTP or WWW,
unbinhex it.  Some communications programs (such as Netscape and
Fetch) do this for you automatically.  If yours does not, try using
Stuffit Expander.  Run the application amulet.sea and select the
directory where want the Amulet source tree to reside.

1.4.5.2 Macintosh Environment Variables

Amulet needs to know the location of your amulet directory for some
bitmap files in the demo programs.  Use SimpleText to create an ASCII
text file called amulet.env in the Preferences folder in the System
Folder of your boot drive.  This text file must contain the full
pathname to your amulet directory.  For example, if your boot drive is
called Hard Disk and the amulet folder is called amulet then the
pathname would be Hard Disk:amulet. Note that there should be no colon
at the end of the pathname and that this file must be an ASCII text
file.

1.4.5.3 Creating the Precompiled Header file

Launch the CodeWarrior IDE application and open the CodeWarrior
project file named AmuletHeaders68K.proj if your Macintosh is running
a 680x0 processor or open AmuletHeadersPPC.proj if your Macintosh is
running a PowerPC processor. These project files are located in
amulet:MAC:pch. Then, select the AmuletHeaders.pch file in the project
window and choose Compile from the Project menu.

1.4.5.4 Compiling The Amulet Library

To build any of the sample programs or to link your own application to
Amulet, you must first build the Amulet library file.  The Amulet 2.0
distribution does not come with any precompiled libraries.

Launch the CodeWarrior application, and open the Amulet library
CodeWarrior project file called amulet:MAC:amulet68K.proj if your
Macintosh is running a 680x0 processor or open
amulet:MAC:amuletPPC.proj if your Macintosh is running a PowerPC
processor.

Choose Make from the Projct menu. Go get a cup of coffee, this'll take
a while.  Compiling Amulet may generate many warnings in Metrowerks,
but there should not be any fatal errors.  If you do get any fatal
errors, please send email to amulet-bugs@cs.cmu.edu so we can try to
help you with your installation.

Once you have a compiled version of the Amulet library you are ready
to write your own Amulet programs and link them to the Amulet library.
Section1.4.5.5 discusses how you can build and run some of the Amulet
samples and test programs.  Your first experience with Amulet
programming should involve the Amulet Tutorial, which includes a
starter program and instructions to acquaint you with the compiling
process.  When you are ready to write your own Amulet program, see
Section1.4.5.6 for instructions about linking your new program to the
Amulet library.

If you would like to build a version of the Amulet libary without
debugging code, you should open the project file
amulet:MAC:amuletNoDebug68K.proj if your Macintosh is running a 680x0
processor or open amulet:MAC:amuletNoDebugPPC.proj if your Macintosh
is running a PowerPC processor. You should also change the Prefix file
in the C/C++ Language Settings for your project file (from the
Preferences Command in the Edit Menu) to be "Am_Prefix.h" instead of
"Am_DebugPrefix.h".

1.4.5.5 Compiling Test Programs and Demos

There are about 10 test programs included in Amulet that test the
lower levels of Amulet: the ORE object system, GEM graphics routines,
OPAL graphical objects, Interactors event handlers, and Widgets.  The
project files for these tests appear in the amulet:MAC directory. You
can build and run these programs to test your installation of Amulet,
but they are not intended to be particularly good examples of Amulet
coding style.

There are some other example programs in AMULET:SAMPLES:*.  These
programs are written how you should write code as an Amulet user, and
are intended to be exemplary code.  Each of these programs have their
own project files located within the sample's directory, and depend on
the Amulet library file.  To generate an executable for any of these
demos, open the project file for the program, and choose Make from the
Project Menu.  You can only compile the samples after you have
successfully compiled the Amulet library.  See Section1.5 for
descriptions of the demos, and Section1.4.5.4 for information on
compiling the Amulet library.

The Amulet demos currently have no feedback during the launch process
so it may appear that the program has crashed while it is still
loading.

1.4.5.6 Writing and Compiling New Programs Using Amulet

The easiest way to create a project file for your own Amulet program
is to start with the stationary project files that are provided with
the Amulet distribution.  They are amulet:MAC:am_stationary68K.stat
for 680x0 processors and amulet:MAC:am_stationaryPPC.stat for PowerPC
processors.  Open the appropriate project file, save it as your new
project file and add your application's .cpp files instead.  At that
point you should be able to successfully compile your Amulet
application.

To start from scratch, you will need to set up your CodeWarrior
project as follows:

 Create a new Metrowerks project file of type MacOS C/C++

 Add your program to the project.

 Add the file amulet.rsrc to the project.  This file contains
important Amulet resources.  Without it, you will get titlebars on
your Amulet Menus, and other ugly effects.

 Add an access path to the amulet directory in the Access Paths
section of the Project Preferences.

 The following settings should be turned on in the Language section
of the Project Preferences: Activate C++ Compiler, ANSI Keywords Only,
Enums always Int. ANSI Strict should be turned off.  Set the prefix
file to Am_DebugPrefix.h if you are using the debugging version of the
Amulet library or Am_Prefix.h if you are not using the debugging
version of the Amulet library.

 For 680x0 projects, the Code Model should be set to Large and Far
Data should be turned on

 Set the Project Type to be application (Type `APPL') and set both
the Preferred Heap Size and Minimum Heap Size = 4096K..

Now you are ready to build your project.

1.5 Test Programs and Demos

The procedure for compiling and executing the demos and test programs
is different depending on your platform.  See Section1.4.3 for
PC-specific instructions, or Section1.4.4 for Unix-specific
instructions on installing Amulet and compiling the tests and samples.

The following list describes each of the sample programs provided with
Amulet:

 hello This program creates a window and displays 'hello world' in it.
You can exit by hitting meta-shift-f1.

 goodbye_button This program creates a button widget on the screen
which quits when pressed.

 goodbye_inter This program displays "goodbye world" in a window, and
an interactor causes the program to quit when the text is clicked on.

 tutorial This program simply creates a window on the screen.  It is
the starting point for all the examples in the Amulet Tutorial.

 checkers This is a two-player checkers game that demonstrates the
multi-screen capabilities of Amulet in Unix.  You can run it on two
screens by supplying the names of the displays when the program is
executed, as in 'checkers my_machine:0.0 your_machine:0.0'.  On the PC
or Macintosh, you can still run this program, but it can only be
displayed on one screen.

 space This program looks a little bit like NetTrek, and demonstrates
many features of Amulet: constraints, bitmaps, polylines, widgets, and
scrolling windows.  Some of the interactions to try are:

  Leftdown in the background of the Short-Range Scan creates a ship

  Leftdown drag on an existing ship moves it

  Middledown+drag (META-leftdown+drag on PC,
OPTION-SHIFT-leftdown+drag on the Macintosh) from one ship to another
draws a phaser beam and destroys the destination ship

  Rightdown+drag (OPTION-leftdown+drag) from one ship to another
establishes a tractor beam which stays attached to the ships through
constraints

  Dragging the white rectangle in the Long-Range Scan changes the
visible area in the Short-Range Scan. You can scroll the visible area
with the scroll-bars or by dragging the white feedback rectangle in
the Long-Range Scan.

 agate This program is used to train a new gesture classifier for use
by the gesture interactor.  See Section5.3.5.6 for more information
about the gesture interactor, agate, and gesture classifiers.

1.6 Amulet Header Files

Usually the only Amulet header file you'll need to include in your
Amulet programs is amulet.h, which will include all of the others for
you.  If you like to use header files as a reference manual, you can
find them in the include/amulet/ directory.

Amulet header files fall into two categories, Basic, and Advanced.
Basic header files define all the standard objects, functions, and
global variables that Amulet users might need to write various
applications.  Advanced header files define lower level Amulet
functions and classes which would be useful to an advanced programmer
interested in creating custom objects in addition to the default
objects Amulet supports.  Most users will only ever include the Basic
header files.

1.6.1 Basic header files

The header file amulet.h includes all the headers most amulet
programmers will ever need to use: standard_slots.h, value_list.h,
gdefs.h, idefs.h, opal.h, inter.h, and widgets.h.  Here is a summary
of the basic header files, listing the major objects, classes, and
functions they define.

 gdefs.h: Am_Style, Am_Font, Am_Point_List, Am_Point_Array,
Am_Image_Array

 idefs.h: Am_Input_Char, predefined Am_Input_Char's

 object.h: Am_Object, Am_Slot, Am_Instance_Iterator,
Am_Slot_Iterator, Am_Part_Iterator

 types.h: Am_String, Am_Value, Am_Error, Am_Wrapper,
Am_Method_Wrapper

 standard_slots.h: standard slot names, Am_Register_Slot_Key,
Am_Register_Slot_Name, Am_Get_Slot_Name, Am_Slot_Name_Exists

 opal.h: predefined Am_Style's, predefined Am_Font's, Am_Screen,
Am_Graphical_Object, Am_Window, Am_Rectangle, Am_Roundtangle, Am_Line,
Am_Polygon, Am_Arc, Am_Text, Am_Bitmap, Am_Group, Am_Map, predefined
formulas, Am_Initialize, Am_Cleanup, Am_Beep, Am_Move_Object,
Am_To_Top, Am_To_Bottom, Am_Create_Screen, Am_Do_Events,
Am_Main_Event_Loop, Am_Exit_Main_Event_Loop, predefined Am_Point_In_
functions, Am_Translate_Coordinates

 formula.h: Am_Formula, Am_Define_Formula, Am_Define_Value_Formula

 value_list.h: Am_Value_List

 text_fns.h: all text editing functions, Am_Edit_Translation_Table

 inter.h: Am_Inter_Location, default interactor method types,
Am_Interactor, Am_Choice_Interactor, Am_New_Points_Interactor,
Am_One_Shot_Interactor, Am_Move_Grow_Interactor,
Am_Text_Edit_Interactor, Am_Where_Function's, interactor debugging
functions, Am_Command, Am_Choice_Command, Am_Move_Grow_Command,
Am_New_Points_Command, Am_Edit_Text_Command, Am_Undo_Handler,
Am_Single_Undo_Object, Am_Multiple_Undo_Object, Am_Abort_Interactor,
Am_Stop_Interactor, Am_Start_Interactor, interactor tracing, undo
handlers, Am_Pop_Up_Window_And_Wait, Am_Finish_Pop_Up_Waiting

 widgets.h: Am_Border_Rectangle, Am_Button, Am_Button_Panel,
Am_Checkbox_Panel, Am_Radio_Button_Panel, Am_Menu, Am_Menu_Bar,
Am_Option_Button, Am_Menu_Line_Command, Am_Vertical_Scroll_Bar,
Am_Horizontal_Scroll_Bar, Am_Scrolling_Group, Am_Text_Input_Widget,
dialog boxes, Am_Selection_Widget,
Am_Selection_Widget_Select_All_Command, Am_Text_Input_Dialog,
Am_Choice_Dialog, Am_Alert_Dialog, Am_Start_Widget, Am_Abort_Widget,
Am_Global_Clipboard, Am_Graphics_Set_Property_Command,
Am_Graphics_Clear_Command, Am_Graphics_Clear_All_Command,
Am_Graphics_Copy_Command, Am_Graphics_Cut_Command,
Am_Graphics_Paste_Command, Am_Undo_Command, Am_Redo_Command,
Am_Graphics_To_Bottom_Command, Am_Graphics_To_Top_Command,
Am_Graphics_Duplicate_Command, Am_Graphics_Group_Command,
Am_Graphics_Ungroup_Command, Am_Show_Alert_Dialog,
Am_Get_Input_From_Dialog, Am_Get_Choice_From_Dialog,
Am_Show_Dialog_And_Wait

 debugger.h: the inspector

 undo_dialog.h: the selective undo dialog box

1.6.2 Advanced header files

All other header files are considered Advanced header files.  They
support advanced Amulet features, such as user-defined objects,
daemons, constraints, and so on.  Most users should never include
these files explicitly.  For users who will be using Amulet's advanced
features, here is a brief summary of the contents of each advanced
header file.

 gem.h: Am_Drawonable, Am_Input_Event, Am_Input_Event_Handlers,
Am_Region

 am_io.h: Am_TRACE

 object_advanced.h: Am_Demon_Queue, Am_Demon_Set, Am_Constraint,
Am_Constraint_Iterator, Am_Dependancy_Iterator, Am_Slot_Advanced,
Am_Object_Advanced, Am_Constraint_Context, Ore_Initialize

 priority_list.h: Am_Priority_List_Item, Am_Priority_List

 symbol_table.h: Am_Symbol_Table

 types.h: NULL, Am_Error, Am_Wrapper, Am_WRAPPER_DECL,
Am_WRAPPER_IMPL, Am_WRAPPER_DATA_DECL, Am_WRAPPER_DATA_IMPL

 formula_advanced.h: Am_Formula_Advanced, Am_Depends_Iterator

 opal_advanced.h: Am_Aggregate, advanced opal object slots,
Am_Draw_Method, Am_Draw, Am_Invalid_Method, Am_Invalidate,
Am_Point_In_Obj_Method, Am_Translate_Coordinates_Method,
Am_State_Store, Am_Item_Function, Am_Invalid_Rectangle_Intersect,
Am_Window_ToDo

 inter_advanced.h: Am_Initialize_Interactors,
Am_Interactor_Input_Event_Notify, Am_Inter_Tracing,
Am_Get_Filtered_Input, Am_Modify_Object_Pos,
Am_Choice_Command_Set_Value, interactor methods, command methods, Undo
handler functions

 widgets_advanced.h: Computed_Colors_Record, Am_Checkbox,
Am_Radio_Button_Item, Am_Menu_Item, widget drawing functions, widget
formula constraints, other widget support functions

1.6.3 Standard Header File Macros

The actual names of the header files described above are slightly
different on each machine.  Long names are truncated on the PC, as
described in Section1.4.3.9.  Directory paths aren't specified in the
same way on the Mac as they are on Unix.  To allow these files to be
included simply without explicit conditional compilation on the
various platforms, we've provided a set of C++ #defines which give
each .h file a standard identifier on all platforms.  These #defines
are in amulet/include/am_inc.h.

You should usually only need to #include <amulet.h> in your program.
If you need to include any of the other header files, you should
#include <am_inc.h> and then include the #defined names of the header
files as found in am_inc.h, instead of the file's actual name.  This
helps ensure machine independant compilation.  For example, if you
needed to include object_advanced.h and opal_advanced.h, the top of
your program might look like:

#include <amulet.h>

#include <am_inc.h>

#include OBJECT_ADVANCED__H

#include OPAL_ADVANCED__H

Visual C++ sometimes has problems with am_inc.h if you have the
precompiled headers option turned on in your project.  Most of the
time, building the project again fixes the problem (you don't need to
do a Build All).  If you get errors such as, "#include expected a
filename, found an indentifier," this is the problem you're
experiencing.  To avoid it in the future, turn off precompiled headers
in your project.

1.7 Parts of Amulet

Amulet is divided into several layers, which each have their own
interface (and chapter of this manual).  The overall picture is shown
below.

Widgets

Opal Graphics

Interactors and Commands

ORE objects and constraints

Gem low-level graphics routines

Window system (X11, Windows, Quickdraw)

The Gem layer provides a machine-independent interface so the rest of
Amulet is independent of the particular window system in use.  Most
programmers will not need to use Gem.  Ore provides a
prototype-instance object system and constraint solving that is used
by the rest of Amulet.  Gem and ORE can each be used as a standalone
system without any of the rest of Amulet, if specific functionality is
required without the overhead of the higher levels of code.  Opal
provides an object-oriented interface to the Gem graphics system, and
the Interactors and Command objects handle processing of input events
from Gem.  At the top is a set of Widgets, including scroll bars,
buttons, menus, text input fields, and dialog boxes.

1.8 Known Bugs

We know about several bugs in Amulet which users might come across,
which we have not found solutions for yet.  Some of them are listed
here.

1.8.1 Linux bugs

Many people experience various problems compiling and running Amulet
on Linux platforms.  Some people get internal compiler errors when
trying to compile with gcc, particularly gcc 2.7.2.  These internal
compiler errors are not consistent.  They happen in a different
section of code each compile, and usually a make clean prevents any of
the errors from occurring.  Some people compile and link successfully,
but then their executable won't run because Linux claims it's not a
properly executable file.  These bugs might be due to improper Linux/
gcc installations, or to bugs in compiler or OS software.  We haven't
found any way to fix these problems yet, and we can't reproduce them
on the Linux machines we have access to, so we've been unable to find
workarounds

Other people have compiled and run Amulet successfully under Linux,
but come across runtime bugs, mostly dealing with the Inspector.
Sometimes if you hit ^q or choose the Objects:Done or Objects:Done All
menu items, Amulet will crash.  The menu items View:Hide Internal
Slots and View:Hide Inherited Slots, among others, don't do anything.
We've traced all of these bugs down to a single problem where gcc
seems to be passing a parameter by reference instead of by value,
giving us bogus pointers.  We're surprised that this bug doesn't cause
more widespread problems.  We believe it is a problem with the Linux
gcc compiler, but so far we have been unable to construct a small
breaking test case, so we can't be sure of this yet.

1.8.2 Visual C++ bugs

Visual C++ 4.1 gets an internal compiler error when trying to compile
the dotted/dashed line code in gwline.cpp.  Because we don't have
access to VC++ 4.1 to debug the problem, we've added a conditional
compiler directive to compile out the inline assembly code when
compiling with VC++ version 4.1 or newer.  Your Amulet code shouldn't
crash, but dotted and dashed lines may not be drawn correctly when you
compile with VC++ 4.1.

1.8.3 Macintosh Bugs

Dotted and dashed lines aren't supported correctly on the Macintosh.
For best results using dotted and dashed lines on any platform, you
should use the predefined Am_Styles Am_Dotted_Line and Am_Dashed_Line
instead of defining your own custom dashed and dotted lines.  These
predefined styles will be supported in future versions of Amulet, but
the dashing and dotting customizations will probably not be supported.

1.9 Changes since Version 1.2

There have been many changes in Amulet since version 1.  In
particular, all code that worked with V1.2 must be edited to compile
with version 2 (for details, see Section1.9.7).  The following
sections provide a summary of the changes, but you should look in the
specific sections of this manual for complete information about
Amulet's new features.

1.9.1 Changes from V2.0 beta to V2.0 official release

1.9.1.1 Minor Changes

 Unix/X now correctly maps some previously unmapped keysyms.

 Inspector startup keys can be reset at runtime from user code.

 Added out of memory dialog box on the Mac.

 Added minimal support for dotted and dashed lines on the Mac.

 Some options set correctly in Mac Project files.

 New 68k and PPC project files for goodbye demos.

 Mac now distinguishes between esc and clear keys correctly.

1.9.1.2 Bug Fixes

 Fixes for GIF files on the PC.  Color GIF images only worked for
certain bit depths on the PC in older versions of Amulet.  All GIF
files were occasionally corrupted in the lower right hand corner.

 Fix for fonts under Unix/X.  Fonts constructed by name sometimes
came up underlined when they shouldn't have.

 Bug fix on Mac to make inverted text styles work correctly.

 Bug fixes to prevent windows from shrinking and sliding around when
they're not supposed to on Windows `95 and fvwm.

 Bug fix on PC for garbage-filled popup windows in menus.

 Bug fix in Windows `95 to support 16 color mode correctly.

 Patch so dotted/dashed line code doesn't cause an internal compiler
error on VC++ 4.1.

 Bug fix on Mac prevents applications from crashing on exit if you
close windows from the window manager.

1.9.2 Changes from V2.0 alpha to V2.0 beta

We have made a few changes between the alpha and beta releases of
V2.0.  They are described in this section.  These should not require
editing your code, if you have already upgraded to V2.0alpha.

1.9.2.1 Major Changes

 Added support for the Macintosh

1.9.2.2 Minor Changes

 New Am_Tab_To_Next_Widget_Interactor for handling tabbing from text
field to text field in a dialog box.

 To support "weird" characters at the top of fonts, changed so
META-character will set the high bit when typed.  Thus META-6 gets the
paragraph sign (char 182, 0xb6).  Using the As_String or cout form
still gets the META-6 version.  Fixed Opal to pass through these
characters.

 Scrolling Groups have new Am_LINE_STYLE slot for the outline of the
scrolling area, which can be NULL.

1.9.2.3 Bug Fixes

 Got rid of memory leaks in testselectionwidgets.

 Makefiles for gcc with shared libraries now works

 Click in text field but not over the text makes cursor go to end
instead of to the beginning

 Fixed bug where option_button popup menu didn't start off in right
place.

 Fixed bug where MS Win95 windows keep moving or shrinking after the
user moves or changes size.

 A fix for slots declared Am_Local, that showed up with instances of
Am_Option_Buttons

1.9.3 Major Changes between V1.2 and V2.0alpha

 Support for gesture recognition, through the new Gesture_Interactor
and the interactive tool Agate which allows gestures to be defined by
demonstration.

 A new undo model that supports selective undo, redo and repeat of
all operations.  The design is described in a conference paper.

 New widgets:

  Graphics Selection Handles widget

  Built-in Command objects for cut, copy, paste, to top and bottom,
group and ungroup, etc.

  Option button widget, that shows one value and pops up a menu

  Built-in dialog boxes for errors and simple queries

 Significantly expanded debugging facilities.

In the interactive Inspector:

  PopUp windows for constraint dependencies, slot properties and
object hierarchies

  Showing which constraints are inherited

  Ability to trace or break when slots are set

  Formulas and Methods now show their names

  Many more kinds of values can be edited

  Flashing the selected object

  Controlling the Interactor tracing options interactively

  Automatic update of the display when slots change

   Also, tracing and breaking on slot change; many more types print
out meaningfully for cout.

 Support for GIFs (pixmaps) on Unix, PC and Mac

 Support for double buffering.

1.9.4 Minor Changes between V1.2 and V2.0alpha

 Menubars now support accelerator characters.

 For text_interactor and text_input_widgets, clicking outside now
stops the interactor or widget, but passes through the click so it
still does whatever other action is desired.

 Provided routines to start, stop and abort widgets and interactors:
Am_Start_Widget, Am_Stop_Widget, Am_Abort_Widget; Am_Start_Interactor,
Am_Stop_Interactor, Am_Abort_Interactor

 References in formulas to slots and objects that do not yet exist
leave the formula uninitialized, which means that now you need fewer
calls to Valid().  In particular, it is safe to do

	obj.GV_Object(SLOT).GV(Am_LEFT)

even if the SLOT of obj does not yet contain a value.  The formula
must return a "real" value before the result of the formula is used
(such as to draw the object).

 You can now destroy windows using the window manager's Kill-Window
or close box, and this is converted into a message to the window.  By
default this deletes the window, but you can override with other
behaviors.

 Added support for popping up modal dialog boxes and waiting for the
user to supply a value.

 We significantly sped up the execution.  Polygons got about 10 times
faster, other parts are about twice as fast.

 A new type of group was added: Am_Resize_Parts_Group which acts like
a regular group, except that if you change the width and height of the
group, it changes the width and height of the parts correspondingly.

 The Amulet libraries can now be dynamically linked using gcc, which
saves LOTS of time when compiling and linking.  This is the default.

 Amulet now works on some new platforms and compilers.  List of known
working platforms:

   Unix:

 OS: SunOS, HP/UX, Linux, IBM AIX, SGI

 Compilers: gcc 2.6.3, gcc-2.7.0, ObjectCenter 2.1.0

   PC

 OS: Windows NT 3.5 and 3.51 and Windows 95

 Compilers: Visual C++ 2.0, 2.1 or 4.0

   Mac

 Compilers: Metrowerks CodeWarrior 7 and 8

1.9.5 Very Minor Changes between V1.2 and V2.0alpha

 Under X, extra move events are flushed to get better performance

 Guarantee that Am_SAVED_OLD_OWNER of command in inter or widget is
always the inter or widget so you can use it in the DO method or
constraints.

 In the PC version, we use console.cpp instead of GW Streams

 You can scroll and cut and paste in the DOS window for debugging

 obj.Text_Inspect(slot) prints out lots of information (like the
inspector) which can be useful for debugging.  This can be invoked
from many debuggers.  Also, obj.Get_Name() can be invoked from the
debugger.

 New value list method: Append

 Under ObjectCenter, you no longer need to have 2-line definition of
objects.  Thus, it now works to do Am_Object o = obj.Get(SLOT);

 Am_Point_In_Leaf and Am_Point_In_Part (in opal.h) have extra
parameter want_groups, that if false makes it not return a group.
Default = true, which is the same as the v1.0 behavior.

 None of the debugging and printing code is included in the generated
binaries if you compile with DEBUG off.  This significantly reduces
code size.

 Advanced slot properties can now be set from the object so you don't
need to use object_advanced.h, including the inherit rule, read-only,
single constraint mode, and demon bits.

 Built-in support for moving objects across multiple windows in the
Move-Grow Interactor.  The feedback object in the move-grow, new_point
and gesture interactors can be a little window (so you can see it in
the background), or if you use a regular object, the interactors will
move the object into the appropriate window.

 Unnamed parts are now inherited.

 Interactors now will beep when aborted explicitly.  You can turn
this off using the Am_INTER_BEEP_ON_ABORT slot.

 Support pending delete, where the text is deleted if you type
something, in the text interactor and text input widget.

 Am_Point_List class for polygons has many more features and has a
consistent interface with the other list-like classes.  Polygons will
now be scaled correctly if their Am_WIDTH and Am_HEIGHT are set.

 Get_Object and GV_Object method in objects that declares that the
return type of the slot is an object, primarily to help construct long
chains of GV's without intermediate variable assignments.

 Default start-when for all widgets changed to
Am_Default_Widget_Start_Char which is "ANY_LEFT_DOWN" to make widgets
start even if shift and control keys are down, and they work on double
clicks.

 If double-click in a text object or text-input widget, the string is
copied into X cut buffer, and it is put into "pending-delete" mode so
the next character will delete it.  Using the middle button on a text
field or object while the cursor is visible will copy the current
contents of the X cut buffer.

1.9.6 Bug Fixes between V1.2 and V2.0alpha

 If an interactor or widget is in a scrolling window, but is outside
the visible region, clicks no longer go through to those interactors
or widgets.

 Fix to make virtual window managers such as tvtwm work under Unix.

 Made interactors with Am_OTHER_WINDOWS = true work, especially for
new windows created after the interactor is created.  Note that the
slot was renamed to be Am_MULTI_OWNERS.

 We eliminated some memory leaks from Amulet.

 New color allocation scheme under X uses a more intelligent color
than black if it runs out of color cells.

 Bounding box for thick, mitred polygons works correctly

 Point_In_Part for polygons works correctly.

 Caps Lock key only affects alphabetic characters on Unix.

1.9.7 Summary of Non-Backwards Compatible Changes

1) All methods must now be declared using the Am_Define_Method_Type,
Am_Define_Method_Type_Impl, and Am_Define_Method macros.  Details are
below.

2) All formulas when assigned into slots should not use
Am_Formula::Create.  No longer ever use Am_Declare_Formula: instead,
just declare the type to be extern Am_Formula.  Details are below.

3) Changed a number of slot names to adhere to a consistent naming
scheme.  Details are below.

4) Moved the functions that control interactors from the COMMAND
object to the interactor itself.  Thus, if you were customizing a
DO_METHOD, you now set that method into the interactor itself instead
of into the COMMAND of the interactor.  Similarly, moved
Am_CREATE_NEW_OBJECT_METHOD to interactor.

5) Changed Am_Create_New_Object_Method to take a Am_Inter_Location,
because the former signature did not include the reference object.

6) The various Get routines all return an Am_Value& instead of various
kinds of slot references.  This should not affect very much code
unless you are using advanced features.

7) New default where: Am_Inter_In_Object_Or_Part and
Am_Inter_In_Text_Object_Or_Part.  These try to be smart about
selecting a part of a group or the object itself.  If you want to
select a group itself, be sure to override the default with
Am_Inter_In.

8) You should no longer call Am_Initialize_Inspector in your code,
because it does not need to be called on each window anymore.
Instead, the inspector is initialized as part of the standard
Am_Initialize.

9) The names of the UNDO handlers were changed to match the Macintosh
and Windows terminology, including slot names and method names and
types.  In particular, UNDO_THE_UNDO changed to REDO.  There are also
new methods to support the selective undo and redo.

10) Changed the Am_OTHER_WINDOWS slot to be Am_MULTI_OWNERS and can be
a list of objects, not just windows.  Can NO LONGER be a single
object: must be a list, and inter's owner (or its window) MUST also be
on the list.  This is to support the multi-window move-grow
interactor.

11) Unnamed parts are now inherited, so you don't have to invent names
for parts just to get them inherited.  If you want a part to NOT be
inherited, you must pass false as the second parameter to Add_Part.

12) Modified Am_Demon_Set and Am_Demon_Queue to have a more C++ like
interface.

13) Interface to Am_Point_List class has entirely changed, to be more
consistent with other Amulet lists.

14) Removed Am_Button_Command, Am_Scroll_Command, and
Am_Text_Input_Command because they are no longer needed.  Use
Am_Command instead.  Details are below.

1.9.7.1 Details

1) Removed Am_Call, Am_Function_Call, Am_Object_Proc type, all of the
Function_Narrow routines, and the old *function* types

- Predefined types of methods include Am_Object_Method,
Am_Where_Method, Am_Custom_Gridding_Method,
Am_Create_New_Object_Method, Am_Text_Edit_Method,
Am_Register_Command_Method, (advanced opal method types =
Am_Draw_Method, Am_Invalid_Method, Am_Point_In_Method,
Am_Translate_Coordinates_Method, Am_Item_Method)

- Assign the method to the slot just using the method_name (which is
really a pointer to a method description structure).

- Define the methods in .h files using the type, e.g.:

extern Am_Where_Method Am_Inter_In;

- If you need a new new type, put Am_Define_Method_Type in a .h file
for each new type of method (new signature of parameters or return
type)

- Put Am_Define_Method_Type_Impl with same name in one .cc file (or if
the Am_Define_Method_Type goes in a .cc file, put
Am_Define_Method_Type_Impl just below it)

- For each method of that type, use Am_Define_Method instead of the
former procedure header.

- To call the method, use code like:

    Am_Object_Method method;

    method = undo_handler.Get(Am_PERFORM_UNDO_THE_UNDO);

    method.Call(undo_handler);

instead of Am_Call or Am_Function_Call.

- Operationally:

- For every procedure that is used as a method, change its definition
to use the Am_Define_Method macro.

- If any of your methods require a new method TYPE, use the
define_method_type and define_method_type_impl macros

- Change the storing of the method in the slot to NOT have any casts
and NOT have an & in front of it.

- Replace all calls of methods to use the new form.

2)

// in .h file:

extern Am_Formula get_window_height;

// in .cc file:

Am_Define_Formula(int, get_window_height) {

... code ...

}

...

  .Set(Am_HEIGHT, get_window_height)

--- Operationally: replace all Am_Formula::Create(*) with just * and
replace all Am_Declare_Formula's with extern Am_Formula

3) Changed the names of all slots that had _PROC or _ACTION to be
_METHOD instead, including all interactor slots.  Also changed
"_POSSIBLE" to _"ALLOWED" in slots names for undo handlers.

14) Do a global replace of Am_Button_Command with Am_Command.  Do a
global replace of Am_Scroll_Command with Am_Command.  Do a global
replace of Am_Text_Input_Command with Am_Command.

1.10 Formal, Legal Language

1.  This License Agreement, effective as of April 1, 1996, is between:
Carnegie Mellon University having a principal place of business at
5000 Forbes Avenue, Pittsburgh, PA 15213-3890 ("CMU"); and a company
("COMPANY").

2.  CMU owns intellectual property rights to the computer software,
electronic information and data, in all forms and versions, identified
as Amulet, described in CMU Docket 96-050 ("Software"), and associated
documentation ("Document"), collectively ("Program").

3.  CMU grants to COMPANY, upon the terms and conditions set out
below, a fully-paid, nonexclusive, world-wide, royalty-free,
non-revocable, commercial license to use the Program, or any portion
thereof, for any purpose, including, but not limited to, the right to
grant sublicenses under CMU's patent and trade secret rights, and
copyrights, including any renewals and extensions, the right to use,
copy adapt, prepare derivative works of, distribute, sell, lease, or
otherwise dispose of, reverse engineer, or disassemble the Software,
or any portion thereof (including all subsequent editions, revisions,
supplements, and versions thereof), and CMU acknowledges that COMPANY
hereby grants no reciprocal rights.

4.  COMPANY acknowledges that the Program is a research tool still in
the development stage, that it is being supplied "as is," without any
accompanying services or improvements from CMU.

5.  CMU MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED
AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS
FOR PURPOSE, OR MERCHANTABILITY, EXCLUSIVITY OR RESULTS OBTAINED FROM
SPONSOR'S USE OF ANY INTELLECTUAL PROPERTY DEVELOPED UNDER THIS
AGREEMENT, NOR SHALL EITHER PARTY HERETO BE LIABLE TO THE OTHER FOR
INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES SUCH AS LOSS OF PROFITS OR
INABILITY TO USE SAID INTELLECTUAL PROPERTY OR ANY APPLICATIONS AND
DERIVATION THEREOF.  CMU DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH
RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT,
OR THEFT OF TRADE SECRETS AND DOES NOT ASSUME ANY LIABILITY HEREUNDER
FOR ANY INFRINGEMENT OF ANY PATENT, TRADEMARK, OR COPYRIGHT ARISING
FROM THE USE OF THE PROGRAM, INFORMATION, INTELLECTUAL PROPERTY, OR
OTHER PROPERTY OR RIGHTS GRANTED OR PROVIDED TO IT HEREUNDER.  THE
USER AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF CMU,
EXPRESSED OR IMPLIED, TO ANY PERSON CONCERNING THE APPLICATION OF OR
THE RESULTS TO BE OBTAINED WITH THE PROGRAM UNDER THIS AGREEMENT.

6.  COMPANY hereby agrees to defend, indemnify and hold harmless CMU,
its trustees, officers, employees, attorneys and agents from all
claims or demands made against them (and any related losses, expenses
or costs) arising out of or relating to COMPANY's and/or its
sublicensees' use of, disposition of, or conduct regarding the
Licensed Technology and/or Licensed Product including but not limited
to, any claims of product liability, personal injury (including, but
not limited to, death) damage to property or violation of any laws or
regulations including, but not limited to, claims of active or passive
negligence.

7.  COMPANY agrees that it will not make any warranty on behalf of
CMU, express or implied, to any person concerning the application of
or the results to be obtained with the Program.

8.  Title to copyright to the Program and to Document shall at all
times remain with CMU, and COMPANY agrees to preserve same.  COMPANY
agrees not to make any copies of the Document except for COMPANY's
internal use, without prior written consent of CMU.  COMPANY agrees to
place the appropriate copyright notice on any such copies.  Nothing
herein shall be deemed to grant any license or rights in any other
technology owned by CMU related to the Program.

9.  COMPANY owns the rights to derivative works made by or on behalf
of COMPANY.  Nothing herein shall be deemed to grant to CMU, or any
other party, any license or any rights in any technology owned by
COMPANY whether or not related to the Program, or any license or any
rights to COMPANY's products whether or not incorporating any portion
of the Software, or any portion of any derivative works thereof, and
CMU acknowledges that CMU has no rights to same.

10.  This Agreement shall be construed, interpreted and applied in
accordance with the laws of the Commonwealth of Pennsylvania.

11.  Nothing in this Agreement shall be construed as conferring rights
to use in advertising, publicity or otherwise any trademark or the
name of "CMU".

12. COMPANY understands that CMU is not responsible for support or
maintenance of the Program.

The complete list of people at CMU by whom Amulet has been developed
by so far is: Brad A. Myers, Alan Ferrency, Rich McDaniel, Robert
C. Miller, Patrick Doane, Andy Mickish, Alex Klimovitski, Amy
McGovern, William Moher, Robert Armstrong, Ashish Pimplapure, Patrick
Doane, Patrick Rogan, Qiang Rao, and Chun K. So.

