*******************************************************************************
* TSIPP NOTE:  This the original README from the photo widget distribution.   *
* The entire distribution is not included with TSIPP, so many of the files    *
* and procedures  described in this file are not present. DO NOT follow the   *
* build procedure described here.                                             *
*******************************************************************************

This is the README file for version 2.4 of the photo widget,
which is designed for use with Tk version 3.6.


DESCRIPTION
-----------

This distribution contains the source for version 2.4 of the "photo"
Tk widget.  A photo widget displays an image, in color if you have a
color workstation, otherwise in monochrome.  The photo widget will
dither the image if necessary, using the Floyd-Steinberg dithering
algorithm.  It should be able to produce some reasonable
representation of the image on any X workstation, including 1-bit
monochrome workstations.  The widget accepts image data in memory in a
fairly general 24-bit/pixel format.  If you have an image in a file,
you need a C procedure to read it into memory for the photo widget to
display.  The distribution includes a procedure to do this for raw PPM
files.

This distribution also includes patches to tk.h, tkInt.h, tkWm.c and
tkWindow.c to maintain a priority-ordered list of windows whose
colormaps the application wants installed, and supply this list to the
window manager using the WM_COLORMAP_WINDOWS property on the
application's top-level windows.  This is the preferred way to get
colormaps installed, according to the ICCCM.  These patches also
implement a "colorfocus" Tcl command which allows the user to control
the priority ordering.  These patches are not part of the photo
widget, but are necessary for the correct appearance of a photo
widget's window when it is not using the default colormap.

Unfortunately there appears to be a bug in olwm and olvwm which causes
them to crash under certain conditions when using the colorfocus stuff
with more than one top-level window.  I am working on a work-around
for this.  If it appears that using the colorfocus facility has
crashed your window manager, I would appreciate knowing the details.

This code has been compiled and tested on Sun-4's running SunOS 4.1.3
and on a Decstation 5000 running Ultrix 4.2 (including running the
widget on one architecture with the X server on the other).

If you find any bugs, or have any comments, suggestions, questions,
etc., contact me via email; my address is paulus@cs.anu.edu.au.  If
you modify the source, to improve functionality or to port it to
another platform, I would appreciate receiving the changes;
context-style diffs are best.


NEW FEATURES AND CHANGES
------------------------

Version 2.4 of the photo widget differs from the version 2.3 in
the following ways:

* A "get" widget subcommand has been added to return the color of a
specified pixel in the image.

* If the `-visual default' option is specified, the widget will use
its parent's visual rather than the screen default visual.

* A bug in readppm.c has been fixed which caused segmentation
violations on machines where sizeof(int) != sizeof(int *).

* The photo widget has been modified to work on machines with 64-bit
longs.  It now assumes that ints are 32 bits; this can be changed by
modifying a typedef.


PHOTO CANVAS ITEMS
------------------

This distribution includes a photo item for canvases.  A photo item
enables you to put an image on a canvas and draw on top of it.  For a
demonstration, source the file photoitem_test.  This code is still
somewhat experimental.  A photo item has to use the same visual and
colormap as the canvas it's on, which at present can only be the
default visual and colormap.

A photo item is created on a canvas by a command like:

	.c create photo x1 y1 x2 y2

where .c is the canvas, (x1,y1) are the coordinates of the top-left
corner of the photo item, and (x2,y2) are the coordinates of the
bottom-right corner.  This command returns the item number of the
photo item; the name to give to FindPhoto is <canvas>-<item number>,
e.g. if the above command returned 23, the name is ".c-23".

If the image data in the photo is changed, you'll have to execute a
command like

	.c move tag 0 0

to get the image redrawn.

The photo item has several configuration options that can be set with
the itemconf canvas option.  They are -blank, -ditherlevel,
-drawinterval, -gamma, -imagesize, -palette, -xshift and -yshift.  All
except the last two are the same as for the photo widget.  The last
two specify the image coordinates to appear at the top-left corner of
the item.

The photo item cannot generate Postscript at present.


INSTALLATION
------------

The source for the photo widget is in tkPhoto.h and tkPhoto.c, with
documentation in doc/photo.n and doc/FindPhoto.n.  Files readppm.c,
writeppm.c and photocopy.c contain C code implementing some useful
Tcl commands for dealing with photo widgets (reading PPM image files,
copying the contents of one photo widget to another, and writing the
contents of a photo widget to a PPM format file).  File photoInit.c
contains initialization code for the photo widget and associated
commands, to be called from tkAppInit.c.

To build a wish with the photo widget included, plus the readppm,
writeppm and photocopy commands, all that is required is (a) to
include the necessary object files in libtk.a and (b) to call
Photo_Init from tkAppInit.c.  The file photo.patch contains patches to
make these changes to Makefile.in and tkAppInit.c.  After applying
these patches, you will need to run configure again to update the
Makefile.

You should also install the patches in the file colorfocus.patch.
This modifies tk.h, tkInt.h, tkWindow.c and tkWm.c to maintain the
WM_COLORMAP_WINDOWS property and add the "colorfocus" command.
Documentation for the colorfocus command is in doc/colorfocus.n.
Strictly speaking, this is not absolutely essential if you plan never
to use a workstation with a writable colormap, but it is recommended.

The installation procedure is as follows:

	1. Get photo-2.4.tar.gz and unpack it in your tk3.6 directory.
	   (e.g. gunzip -c photo-2.4.tar.gz | tar xvf -)

	2. patch <photo.patch

	3. patch <colorfocus.patch

	4. ./configure

	5. make

This will recompile tk*.c (because of the changes to tk.h and
tkInt.h), and make libtk.a and wish.  Note that if you are using
shared libraries, you may have switches like `-L/usr/local/tk3.6/lib -L.'
in the command line for linking wish.  If this is the case, and you
have an old version of libtk.so in /usr/local/tk3.6/lib, you will need
to either delete the old version or reverse the order of the -L
switches to pick up the new version of the library.

You can then test the photo widget with the command:

	./wish -f photo_test

This should display the image in teapot.ppm, which is a ray-traced
image of a teapot.  Move the cursor into the image and press 'q' to
quit, '1' .. '9' to change the gamma value ('4' gives a gamma of 1),
'a', 'b', 'f', 'n' or 'm' to change the palette, 'r' to reread the
image, 'd' to dither the image, or 'c' to copy it into a new photo
widget.  You will have to press 'd' to get the image displayed
correctly after changing the palette or gamma value; after switching
between a color palette ('a', 'b', or 'f') and a monochrome palette
('m' or 'n'), you will have to re-read the image ('r').  See
photo_test for details.

To try out the photo item, use the command

	./wish -f photoitem_test

This should display the teapot image on a canvas with a red diagonal
line across it.  If you click with the left mouse button, a small
green square should appear centered on the point where you clicked.

To include the photo widget in your program, you need to add a call to
Tcl_CreateCommand in your main program to establish the `photo' Tcl
command.  Linking with libtk.a should then include tkPhoto.o, assuming
you have followed the steps above.  You will probably need to write a
C language procedure to supply image data to the widget; look at
readppm.c to see how this is done.


COLORMAP CONSIDERATIONS
-----------------------

If the photo widget is using a visual other than the default, or if
its palette requires more colors than are available in the default
colormap, then it will use a private colormap.  The patches to
tkWindow.c and tkWm.c ensure that the window then gets put in the
colormap-windows list (i.e. the WM_COLORMAP_WINDOWS property).  With
some window managers and some workstations (e.g. those with several
colormaps), this is sufficient to ensure that the window's colormap
will get installed.  For instance, olwm (and olvwm) have a `colormap
focus follows mouse' mode in which olwm installs the colormap of the
window in the list which the cursor was most recently in.

In other cases, it will be necessary to bring the window to the front
of the list to ensure that its colormap gets installed.  This can be
accomplished using the "colorfocus" Tcl command.  When to do this is a
question of user interface policy; my suggestion is to include class
bindings such as

	bind Photo <Enter> {colorfocus %W}
	bind Toplevel <Enter> {colorfocus %W}

This will have the effect of installing a photo's colormap whenever
the pointer enters it; its colormap will stay installed until the user
moves the pointer into another photo widget, or out of the top-level
window and back into any of the top-level windows of the application.

I have chosen to implement a global colormap focus policy by
maintaining a single priority-ordered list of windows for each screen
which an application is using.  This same list is placed in the
WM_COLORMAP_WINDOWS property for all top-level windows of the
application on that screen.  Thus, the window manager should install
the colormap for the window with the Tk colormap focus whenever it
assigns its colormap focus to any of the application's top-level
windows.

The Tk colormap focus was implemented this way partly for conformity
with the way that the Tk input focus operates, but the situation is
confused somewhat by the fact that it is possible to have more than
one colormap installed, and thus more than one colormap focus, on some
workstations.  Also, it is not completely clear from the ICCCM whether
it is legal for a top-level window to have another top-level window's
descendent in its WM_COLORMAP_WINDOWS property (some of the discussion
seems to presuppose that this won't ever happen, but it's not
prohibited anywhere).

One alternative would be to have a separate local Tk colormap focus
for each top-level window.  I would be interested to hear people's
views on the pros and cons of the global colormap focus policy I have
implemented versus other alternatives.


IMAGE FORMAT
------------

The photo widget accepts most formats which have one byte (unsigned char)
for red, green and blue for each pixel.  The image data supplied to the
widget (from C code) are described by the following header:

	typedef struct image_block {
	    unsigned char *ptr;		/* points to image data */
	    int		width;		/* horiz # pixels in block */
	    int		height;		/* vert # pixels in block */
	    int		pitch;		/* # bytes stored per line */
	    int		pixel_size;	/* # bytes per pixel */
	    int		comp_off[3];	/* address offset to R,G,B components */
	} PhotoImage;

The photo widget uses this as follows: the components of the first pixel
of the first line are at ptr[comp_off[0]], ptr[comp_off[1]], and
ptr[comp_off[2]].  The next pixel on the same line is at ptr + pixel_size,
and the first pixel on the next line is at ptr + pitch.

Having the pitch, pixel_size and comp_off[] fields lets the widget handle
all formats in which the component bytes are regularly spaced, including:

* the 'standard' RGBRGB... format stored by scan-lines, with an arbitrary
  amount of padding at the end of each scan-line (e.g. PPM format).

* formats where the components are in a different order (e.g. BGR)

* formats where there are extra components (e.g. an alpha channel)

* line-interleaved formats (where you get a red scan-line, then a green
  scan-line, then a blue scan-line, or some other order).

* formats where the components are stored by plane (e.g. a complete red
  image, then a green image, then a blue image).

* formats where the pixels are stored by columns rather than scan-lines.

* formats where the pixels in a row are stored in reverse order, or where
  the scan-lines are stored in reverse order (you need to make ptr point
  to the end of the row or image respectively).

It won't cope with an interlaced format, where you get an array of even
lines followed by an array of odd lines.


Paul Mackerras
Dept. of Computer Science
The Australian National University.
paulus@cs.anu.edu.au
