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.

Section 1.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 Section 1.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 Section 1.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 Section 1.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. Section 1.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 Section 1.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 Section 1.5 for descriptions of the demos, and Section 1.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:

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 Section 1.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:

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 Section 1.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 Section 1.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 Section 1.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 Section 1.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 debug-ging 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.

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 Section 1.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 Section 1.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. Section 1.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 Section 1.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 Section 1.5 for descriptions of the demos, and Section 1.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:

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 Section 1.4.3 for PC-specific instructions, or Section 1.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:
agate This program is used to train a new gesture classifier for use by the gesture interactor. See Section 5.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.

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.

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 Section 1.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.

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 Section 1.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

1.9.1.2 Bug Fixes

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

1.9.2.2 Minor Changes

1.9.2.3 Bug Fixes

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

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

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

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).
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

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

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.


Last Modified: 03:05pm EDT, May 24, 1996