#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	movietool-1.1
# This archive created: Tue Jun 26 13:06:26 1990
export PATH; PATH=/bin:$PATH
if test ! -d 'movietool-1.1'
then
	echo shar: creating directory "'movietool-1.1'"
	mkdir 'movietool-1.1'
fi
echo shar: entering directory "'movietool-1.1'"
cd 'movietool-1.1'
echo shar: extracting "'audio.c'" '(657 characters)'
if test -f 'audio.c'
then
	echo shar: will not over-write existing file "'audio.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'audio.c'
	Xvoid audio (audiofile)
	Xchar *audiofile;	/* Filename relative to AUDIODIR */
	X{
	X
	X/* The AUDIODIR is the directory of *.au audio files */
	X/* The AUDIOPLAYER is the program that will play audio files */
	X
	X/* It would be good to test for the existence of /dev/audio.
	X * I don't know if there is a faster way than opening the device,
	X * which I anyway believe gives an audible click when being opened.
	X * For lack of anything better, I just check for "sparc" */
	X
	X#if defined AUDIODIR && defined AUDIOPLAYER
	X	char buf[200];
	X	sprintf (buf, "%s %s/%s &", AUDIOPLAYER, AUDIODIR, audiofile);
	X	system (buf);	/* execute the command in the background (& flag) */
	X#endif
	X}
SHAR_EOF
if test 657 -ne "`wc -c < 'audio.c'`"
then
	echo shar: error transmitting "'audio.c'" '(should have been 657 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'frames.c'" '(6008 characters)'
if test -f 'frames.c'
then
	echo shar: will not over-write existing file "'frames.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'frames.c'
	X#include "movietool.h"
	X#include <stdio.h>
	X#include <pixrect/pr_io.h>
	X
	X/* Global variables */
	X
	Xextern Canvas_par canvas_par;
	Xextern int identical_colormaps;
	Xextern int encoded_flag;
	Xextern int xor_flag;
	Xextern struct pixrect *pr_mag(), *pr_load_encoded_image();
	X
	XImage *first_frame;	/* The first image of the movie sequence */
	X
	X/* Local variables */
	X
	Xstatic void copy_colormap ();
	Xstatic struct pixrect * pr_xor ();
	X
	Xint collect_images (num_files, filenames, zoom, window_cmap, dx, dy, dw, dh)
	Xint num_files;			/* Number of file names */
	Xchar **filenames;		/* File names */
	Xint zoom;			/* Zoom factor */
	Xcolormap_t window_cmap;		/* window's default colormap */
	Xint dx, dy, dw, dh;		/* selecting pixrect region */
	X{
	X	Image *frame, *left_frame;
	X	struct pixrect *pix, *region_pix;
	X	colormap_t *colormap, *global_cmap;
	X	int num_images = 0, image;
	X	struct rasterfile raster;
	X	FILE *fp;
	X	
	X	printf("Number of files to be checked on: %d\n", num_files);
	X
	X	first_frame = (Image *)malloc (sizeof (Image));
	X	first_frame->frameno = 1;
	X	first_frame->left = NULL;
	X	first_frame->right = NULL;
	X	frame = first_frame;	/* Initial frame */
	X	canvas_par.depth = 1;	/* Assume monochrome from the outset */
	X
	X	/* Collect images in the sequence in which they are provided */
	X
	X	for (image=0; image < num_files; image++) {
	X
	X		printf ("%s: ", filenames[image]);
	X		fflush (stdout);
	X
	X		if ( (fp=fopen (filenames[image], "r")) == NULL) {
	X			printf ("Cannot open file (skipped)   \n");
	X			fclose (fp); continue;
	X		}
	X		if (pr_load_header (fp, &raster) == PIX_ERR) {
	X			printf ("Bad header (skipped)   \n");
	X			fclose (fp); continue;
	X		}
	X
	X		colormap = (colormap_t *) NULL;
	X		/* Ignore colormap (by colormap=NULL) for monochrome pictures 
	X	 	 * and when assuming identical colormaps */
	X		if (raster.ras_maptype == RMT_NONE)
	X			;
	X		else if (raster.ras_maptype == RMT_EQUAL_RGB) {
	X			if (identical_colormaps && canvas_par.depth == 8)
	X				;
	X			else if (raster.ras_depth == 8)	/* Allocate */
	X				colormap = (colormap_t *)calloc
	X					(1, sizeof (colormap_t));
	X			if (pr_load_colormap (fp, &raster, colormap)==PIX_ERR) {
	X				printf ("Bad colormap (skipped)   \n");
	X				fclose (fp); free(colormap); continue;
	X			}
	X			/* Set window colormap to 1st colormap read */
	X			if (identical_colormaps && canvas_par.depth == 8)
	X				colormap = global_cmap;
	X			else if (colormap && canvas_par.depth != 8) {
	X				global_cmap = colormap;
	X				/* window_cmap has entries 0 and 255 modified */
	X				copy_colormap (colormap, &window_cmap);
	X				canvas_par.depth = 8;
	X			}
	X		} else {
	X			printf ("I don't know colormap type=%d (skipped)   \n",
	X				raster.ras_maptype);
	X			fclose (fp); continue;
	X		}
	X
	X		printf ("loading...");
	X		fflush (stdout);
	X		if (encoded_flag && raster.ras_type == RT_BYTE_ENCODED) {
	X			frame->ras_type = RT_BYTE_ENCODED;
	X			pix = pr_load_encoded_image (fp, &raster);
	X		} else {
	X			frame->ras_type = RT_STANDARD;
	X			pix = pr_load_image (fp, &raster, colormap);
	X		}
	X		fclose (fp);
	X
	X		if (pix == PIXRECT_NULL) {
	X			printf ("Trouble loading image (skipped)   \n");
	X			free(colormap); continue;
	X		}
	X
	X		/* Save file name */
	X		frame->filename = filenames[image];
	X
	X		/* Select pixrect subregion */
	X
	X		if (dx || dy || dw || dh) {
	X			printf ("subregion...");
	X			fflush (stdout);
	X			region_pix = mem_create (dw, dh, pix->pr_depth);
	X			if (pr_rop (region_pix, 0, 0, dw, dh,
	X				PIX_SRC | PIX_DONTCLIP, pix, dx, dy)==PIX_ERR) {
	X				printf ("(couldn't copy subregion)");
	X				fflush (stdout);
	X			} else {
	X				pr_destroy (pix);
	X				pix = region_pix;
	X			}
	X		}
	X
	X		/* Zoom picture */
	X
	X		if (zoom && frame->ras_type == RT_STANDARD) {
	X			printf ("zooming...");
	X			fflush (stdout);
	X			/* Zoom in the x-direction, only */
	X			frame->pix = pr_mag (pix, zoom, 1);
	X			if (frame->pix == PIXRECT_NULL) {
	X				printf ("(bad zoom)");
	X				fflush (stdout);
	X				frame->pix = pix;
	X			} else
	X				pr_destroy (pix);
	X		} else
	X			frame->pix = pix;
	X
	X		/* XOR'ed pixrect */
	X
	X		if (xor_flag && num_images > 0) {
	X			printf ("XOR-ing...");
	X			fflush (stdout);
	X			frame->xor = pr_xor (frame->left->pix, frame->pix);
	X			if (frame->xor == PIXRECT_NULL) {
	X				printf ("(couldn't XOR)");
	X				fflush (stdout);
	X			}
	X		} else
	X			frame->xor = PIXRECT_NULL;
	X
	X		/* Determine required canvas size */
	X		if (frame->pix->pr_size.x > canvas_par.width)
	X			canvas_par.width = frame->pix->pr_size.x;
	X		if (frame->pix->pr_size.y > canvas_par.height)
	X			canvas_par.height = frame->pix->pr_size.y;
	X
	X		frame->map = colormap;
	X		frame->frameno = ++num_images;
	X		printf (" (size %dx%dx%d)",
	X			pix->pr_size.x * (zoom ? zoom : 1),
	X			pix->pr_size.y * (zoom ? zoom : 1),
	X			pix->pr_depth);
	X		printf ("   \r");	/* Carriage return, no newline */
	X		fflush (stdout);
	X
	X		/* Allocate the next frame */
	X
	X		if (image < (num_files-1)) {
	X			frame->right = (Image *)malloc (sizeof (Image));
	X			left_frame = frame;
	X			frame = frame->right;
	X			frame->left = left_frame;
	X		}
	X		frame->right = NULL;
	X	}
	X	printf ("\n");
	X	return (num_images);
	X}
	X
	Xstatic void copy_colormap (c1, c2)
	Xcolormap_t *c1, *c2;
	X{
	X	register int i;
	X
	X	i = c1->length;
	X	c2->type   = c1->type;
	X	c2->length = i;
	X	bcopy (c1->map[0], c2->map[0], i);
	X	bcopy (c1->map[1], c2->map[1], i);
	X	bcopy (c1->map[2], c2->map[2], i);
	X	/* Set 1st and last entry to black and white, respectively */
	X	/* Disabled:
	X	c2->map[0][0] = c2->map[1][0] = c2->map[2][0] = 0;
	X	i = c1->length - 1;
	X	c2->map[0][i] = c2->map[1][i] = c2->map[2][i] = 255;
	X	*/
	X}
	X
	Xstatic struct pixrect *pr_xor (pr1, pr2)	/* pr1 ^ pr2 (XOR op) */
	Xstruct pixrect *pr1, *pr2;
	X{
	X	struct pixrect *xor;
	X	int x = pr2->pr_size.x;
	X	int y = pr2->pr_size.y;
	X
	X	if (pr1->pr_size.x != x || pr1->pr_size.y != y ||
	X		pr1->pr_depth != pr2->pr_depth)
	X		return (PIXRECT_NULL);
	X	if ((xor = mem_create (x, y, pr2->pr_depth)) == PIXRECT_NULL)
	X		return (PIXRECT_NULL);
	X	if (pr_rop (xor, 0, 0, x, y, PIX_SRC | PIX_DONTCLIP, pr1, 0, 0)
	X		== PIX_ERR) {
	X		pr_destroy (xor);
	X		return (PIXRECT_NULL);
	X	}
	X	if (pr_rop (xor, 0, 0, x, y, PIX_SRC^PIX_DST | PIX_DONTCLIP, pr2, 0, 0)
	X		== PIX_ERR) {
	X		pr_destroy (xor);
	X		return (PIXRECT_NULL);
	X	}
	X	return (xor);
	X}
SHAR_EOF
if test 6008 -ne "`wc -c < 'frames.c'`"
then
	echo shar: error transmitting "'frames.c'" '(should have been 6008 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'main.c'" '(9278 characters)'
if test -f 'main.c'
then
	echo shar: will not over-write existing file "'main.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'main.c'
	X/*
	X * This file is part of:
	X * Movietool: display a succession of rasterfile frames in real-time
	X *
	X * Copyright 1989, 1990 by Ole H. Nielsen
	X *
	X * Author: Ole H. Nielsen
	X *         Lab of Applied Physics, Bygn. 307
	X *         Technical University of Denmark, DK-2800 Lyngby
	X *         E-mail: ohnielse@ltf.dth.dk
	X */
	X#include "movietool.h"
	X#include <stdio.h> 
	X#include <suntool/canvas.h>
	X#include <suntool/panel.h>
	X#include <suntool/scrollbar.h>
	X
	X#define ICONIMAGE	"movietool.icon"
	X#define WIDTH	500
	X#define HEIGHT	500
	X#define PANEL_FONT	"/usr/lib/fonts/fixedwidthfonts/screen.b.12"
	X#define AUDIOFILE	"movietool.au"
	X
	X/* global declarations */
	X
	Xextern int	collect_images();
	Xextern void	audio();
	Xextern void	create_panel_items(), canvas_repaint_proc();
	Xextern char	*title;
	Xextern Image	*first_frame;
	X
	XFrame		window_frame;	
	XWindow 		panel; /* Declaring as Window to get colormap capability */
	XCanvas		canvas;
	Xstatic Cursor	cursor;
	XPixwin		*canvaspw, *panelpw, *windowpw;
	XPixfont		*panelfont;
	XCanvas_par	canvas_par;
	Xvoid		put_color ();
	Xvoid		usage();
	Xchar		colormapname[20];
	Xint		num_images = 0;		/* Total no. of images loaded */
	Xint		background_color = 0;	/* Canvas background color */
	X		/* True if all images share the same colormap */
	Xint		identical_colormaps	= FALSE;
	X		/* True if using RT_BYTE_ENCODED rasters */
	Xint		encoded_flag	= FALSE;
	X		/* True if using XOR when showing successive images */
	Xint		xor_flag	= FALSE;
	X		/* Zoom factor.  Zero means no zoom */
	Xint		zoom		= 0;
	X
	X/* local declarations */
	X
	Xstatic int	audio_flag	= FALSE; /* Whether audio will be output */
	Xstatic int	panel_exists	= FALSE; /* Whether the control panel exists */
	Xstatic short	icon_image[]={		/* Movietool icon */
	X#include ICONIMAGE
	X};
	Xmpr_static(icon_pixrect, 64, 64, 1, icon_image);
	X
	Xmain(argc, argv)
	Xint argc; char **argv;
	X{
	X	extern char *optarg;
	X	extern int optind, opterr;
	X	Icon icon;
	X	static unsigned char red[CMS_SIZE], green[CMS_SIZE], blue[CMS_SIZE];
	X	static colormap_t window_cmap = { RMT_NONE, 0, { red, green, blue } };
	X	int background_flag = FALSE;
	X	int i, j, argcoffset=1, width, height;
	X	int dx=0, dy=0, dw=0, dh=0;
	X	int c, errflag = 0;
	X
	X	if (getenv ("WINDOW_PARENT") == NULL) {
	X		fprintf (stderr, "%s can only be run under SunView.\n",argv[0]);
	X		exit (1);
	X	}
	X
	X	/* Open the base frame.  Note that window_create consumes SunView args*/
	X	icon = icon_create (ICON_IMAGE, &icon_pixrect, 0);
	X	window_frame = window_create (0, FRAME, 
	X		FRAME_ARGC_PTR_ARGV, &argc, argv,
	X		FRAME_LABEL, title,
	X		FRAME_ICON, icon,
	X		FRAME_CMDLINE_HELP_PROC, usage,
	X		FRAME_INHERIT_COLORS, TRUE,
	X		0);
	X
	X	/* Get command line arguments */
	X
	X	while ((c = getopt(argc, argv, "iz:s:Xeab")) != -1)
	X		switch (c) {
	X		case 'i':
	X			identical_colormaps = TRUE;
	X			printf ("Colormap of 1st frame used throughout.\n");
	X			break;
	X		case 'z':
	X			(void) sscanf (optarg, "%d", &zoom);
	X			if (zoom > 10 || zoom < 2)  {
	X				fprintf (stderr, "Bad arg=%d to -zoom.\n",zoom);
	X				zoom = 0;
	X				errflag++;
	X			} else
	X				(void) printf ("Zoom by factor %d.\n", zoom);
	X			break;
	X		case 's':
	X			j =	sscanf (optarg,		"%d", &dx) +
	X				sscanf (argv[optind],	"%d", &dy) +
	X				sscanf (argv[optind+1],	"%d", &dw) +
	X				sscanf (argv[optind+2],	"%d", &dh);
	X			if (j != 4 || dx < 0 || dy < 0 || dw < 2 || dh < 2) {
	X				(void) fprintf (stderr, "Bad args to -sub.\n");
	X				errflag++;
	X			} else {
	X				(void) printf (
	X				"Displaying subregion at %d,%d of size %d,%d.\n"
	X					, dx, dy, dw, dh);
	X				optind += 3;	/* Warning in "man 3 getopt" */
	X			}
	X			break;
	X		case 'X':
	X			xor_flag = TRUE;
	X			printf ("XOR operations will be used when playing.\n");
	X			break;
	X		case 'e':
	X			encoded_flag = TRUE;
	X			printf ("RT_BYTE_ENCODED images will be used.\n");
	X			break;
	X		case 'a':
	X			audio_flag = TRUE;
	X#ifdef sparc
	X			printf ("Listen...\n");
	X#endif
	X			break;
	X		case 'b':
	X			background_flag = TRUE;
	X			printf ("Canvas background colour will be set\n");
	X			break;
	X		case '?':
	X			errflag++;
	X			break;
	X		}
	X
	X	if (encoded_flag && (dx || dy || dw || dh)) {
	X		printf ("-e switch is incompatible with subregion.\n");
	X		errflag++;
	X	}
	X
	X	if (errflag) {
	X		(void) usage (argv[0]);
	X		exit (1);
	X	}
	X
	X	/* Initial canvas parameters */
	X	canvas_par.width		= WIDTH;	
	X	canvas_par.height		= HEIGHT;
	X	canvas_par.depth		= 1;
	X	canvas_par.canvas_width		= WIDTH;	
	X	canvas_par.canvas_height	= HEIGHT;
	X
	X	num_images = collect_images (argc - optind, argv + optind,
	X		zoom, window_cmap, dx, dy, dw, dh);
	X
	X	(void) printf ("Number of frames loaded in: %d.\n", num_images);
	X	if (num_images <= 0) {
	X		(void) usage (argv[0]);
	X		exit (1);
	X	}
	X	if (background_flag)
	X		background_color = get_upper_left_color (first_frame);
	X
	X	/* create a panel for the tool to hold control panels */
	X	if ((panelfont = pf_open(PANEL_FONT)) == NULL) {
	X		fprintf(stderr, "Cannot open font %s.\n", PANEL_FONT);
	X		exit(1);
	X	}
	X	if (num_images > 1) {
	X		panel_exists = TRUE;
	X		panel = window_create (window_frame, PANEL,
	X			WIN_FONT, panelfont, 
	X			0);
	X		(void) create_panel_items ();
	X		(void) window_fit_height (panel);
	X	}
	X
	X	/* Create canvas for display purposes */
	X
	X	canvas = window_create (window_frame, CANVAS,
	X		CANVAS_RETAINED,	TRUE,
	X		CANVAS_FIXED_IMAGE,	FALSE,
	X		CANVAS_AUTO_CLEAR,	FALSE,
	X		CANVAS_AUTO_SHRINK,	FALSE,
	X		CANVAS_AUTO_EXPAND,	TRUE,
	X		WIN_WIDTH,		WIDTH,
	X		WIN_HEIGHT,		HEIGHT,
	X		CANVAS_WIDTH,		canvas_par.width,
	X		CANVAS_HEIGHT,		canvas_par.height,
	X		CANVAS_DEPTH,		canvas_par.depth,
	X		CANVAS_REPAINT_PROC,	canvas_repaint_proc,
	X		0);
	X
	X	/* Initialize canvas properties */
	X
	X	/* Get pixwin for displaying movie */
	X	canvaspw = (Pixwin *)window_get (canvas, CANVAS_PIXWIN);
	X
	X	if (canvas_par.depth == 1) {		/* MONOCHROME */
	X		(void) window_set (canvas,
	X			CANVAS_FAST_MONO, TRUE,
	X			0);
	X		if (window_get (canvas, CANVAS_FAST_MONO))
	X			fprintf (stderr, "Using frame-buffer's fast overlay plane\n");
	X		else
	X			fprintf (stderr, "No frame-buffer overlay plane available\n");
	X	} else if (canvas_par.depth == 8) {		/* COLOR */
	X		windowpw = (Pixwin *)window_get (window_frame, WIN_PIXWIN);
	X		if (panel_exists)
	X			panelpw = (Pixwin *)window_get (panel, WIN_PIXWIN);
	X		(void) sprintf (colormapname, "movietool%d", getpid () );
	X		(void) pw_setcmsname (windowpw, colormapname);
	X		if (panel_exists)
	X			(void) pw_setcmsname (panelpw, colormapname);
	X		(void) pw_setcmsname (canvaspw, colormapname);
	X		(void) put_color (&window_cmap);
	X		if (windowpw->pw_pixrect->pr_depth < 8)
	X			fprintf (stderr, "%s - WARNING: color frames will not make sense on a monochrome display.\n", argv[0]);
	X	} else {
	X		(void) fprintf (stderr, "%s: I don't know canvas depth=%d.\n",
	X			argv[0], canvas_par.depth);
	X		exit(1);
	X	}
	X
	X	/* Scrollbars must be set after CANVAS_FAST_MONO (SunView, p. 125) */
	X	if (canvas_par.height > HEIGHT)
	X		(void) window_set (canvas,
	X		WIN_VERTICAL_SCROLLBAR,
	X			scrollbar_create (SCROLL_LINE_HEIGHT, 20, 0),
	X		0);
	X	if (canvas_par.width > WIDTH)
	X		(void) window_set (canvas,
	X		WIN_HORIZONTAL_SCROLLBAR, 
	X			scrollbar_create (SCROLL_LINE_HEIGHT, 20, 0),
	X		0);
	X
	X	/* Disable mouse inside canvas */
	X	cursor = window_get (canvas, WIN_CURSOR);
	X	(void) cursor_set (cursor,
	X		CURSOR_SHOW_CURSOR, FALSE,
	X		0);
	X	(void) window_set (canvas,
	X		WIN_CURSOR, cursor,
	X		0);
	X
	X	(void) window_fit (canvas);
	X	(void) window_fit (window_frame);
	X	(void) step_proc ();
	X
	X	/* if (panel_exists)
	X		(void) paneledit_init (window_frame);	/* Panel editing */
	X
	X	if (audio_flag)		/* Fanfare */
	X		(void) audio (AUDIOFILE);
	X
	X	(void) window_main_loop (window_frame);
	X
	X	exit (0);
	X}
	X
	X#define SHOW(string) (void) fprintf (stderr, (string))
	X
	Xstatic void usage(progname)
	Xchar *progname;
	X{
	X	(void) fprintf (stderr, "Usage: %s\n", progname);
	X	SHOW("       -z (or -zoom) factor - Zoom picture by factor\n");
	X	SHOW("       -s (or -sub) x y w h - Pick out subregion of raster\n");
	X	SHOW("       -i (or -ident)       - Identical colormaps used\n");
	X	SHOW("       -X (or -XOR)         - Play with XOR operations\n");
	X	SHOW("       -e (or -encoded)     - Use encoded rasters (saves RAM)\n");
	X	SHOW("       -a (or -audio)       - Play audio file\n");
	X	SHOW("       -b (or -background)  - Set background color to 1st pixel\n");
	X	SHOW("       file [file...]       - Sun raster files to be displayed\n");
	X}
	X
	X/* Set the colormap for the current frame */
	Xvoid put_color (cmap)
	Xcolormap_t *cmap;
	X{
	X	if ( ! cmap) return;
	X	(void) pw_putcolormap (windowpw, 0, CMS_SIZE,
	X		cmap->map[0], cmap->map[1], cmap->map[2]);
	X	if (panel_exists)
	X		(void) pw_putcolormap (panelpw, 0, CMS_SIZE,
	X			cmap->map[0], cmap->map[1], cmap->map[2]);
	X	(void) pw_putcolormap (canvaspw, 0, CMS_SIZE,
	X		cmap->map[0], cmap->map[1], cmap->map[2]);
	X}
	X
	X#define FLAG 0x80
	X
	X/* Select the background color as the color of uppermost left pixel
	X * of the first frame.  Might be made more sophisticated in the future */
	X
	Xstatic int get_upper_left_color (frame)
	XImage *frame;
	X{
	X	register unsigned char *image;
	X	int color;
	X
	X	if (frame->ras_type == RT_STANDARD) {
	X		image = (unsigned char *) mpr_d(frame->pix)->md_image;
	X		color = *image;			/* First pixel of image */
	X	} else if (frame->ras_type == RT_BYTE_ENCODED) {
	X		image = (unsigned char *) frame->pix->pr_data;
	X		if (*image == FLAG) {		/* FLAG, Repeat count, color */
	X			if (*(image+1))
	X				color = *(image+2);
	X			else
	X				color = FLAG;	/* Count 0 means pixel==FLAG */
	X		} else
	X			color = *image;		/* First pixel of image */
	X	} else
	X		color = 0;
	X
	X	return color;
	X}
SHAR_EOF
if test 9278 -ne "`wc -c < 'main.c'`"
then
	echo shar: error transmitting "'main.c'" '(should have been 9278 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'movietool.c'" '(15813 characters)'
if test -f 'movietool.c'
then
	echo shar: will not over-write existing file "'movietool.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'movietool.c'
	X/*
	X * Movietool: display a succession of rasterfile frames in real-time
	X *
	X * Copyright 1989, 1990 by Ole H. Nielsen
	X *
	X * Author: Ole H. Nielsen
	X *         Lab of Applied Physics, Bygn. 307
	X *         Technical University of Denmark, DK-2800 Lyngby
	X *         E-mail: ohnielse@ltf.dth.dk
	X */
	X#include "movietool.h"
	X#include <stdio.h>
	X#include <suntool/canvas.h>
	X#include <suntool/scrollbar.h>
	X#include <suntool/panel.h>
	X#include <suntool/alert.h>
	X#include <sys/types.h>
	X#include <sys/timeb.h>
	X
	X/* global declarations */
	X
	Xextern Frame	window_frame;
	Xextern Window 	panel;
	Xextern Canvas	canvas;
	Xextern Pixwin	*canvaspw;
	Xextern Image	*first_frame;
	Xextern Canvas_par canvas_par;
	Xextern int	num_images;
	Xextern int	identical_colormaps;
	Xextern int	xor_flag;
	Xextern void	my_pw_rop ();
	Xextern int	encoded_flag;
	Xextern int	zoom;
	Xextern int	background_color;
	X
	Xchar	*title = "Movietool";	/* Title appearing in tool's top bar */
	XImage	*current_frame = (Image *)NULL;	/* The image being displayed */
	Xint	playing = FALSE;	/* True if Play button was pressed */
	Xint	clipping = TRUE;	/* False if copying encoded images */
	X				/* onto framebuffer without clipping */
	X
	X/* local declarations */
	X
	X#define MAX_FRAMES_PER_SEC 100
	X#define FORWARD 0
	X#define BACKWARD 1
	X
	Xstatic void	display_frame ();
	Xstatic int	current_number = 0;	/* Current image's number */
	Xstatic int	step = 1;		/* Stepping +1 or -1 */
	Xstatic int	auto_reverse = FALSE;	/* Auto-reverse movie */
	Xstatic int	repeat = FALSE;		/* Repeat movie */
	Xstatic int	xor_rop;		/* Use XOR raster-ops */
	Xstatic int	xor_show = FALSE;	/* Show the XOR'ed images */
	Xstatic int	Halt = FALSE;		/* True if STOP button was pressed */
	Xstatic unsigned frames_per_sec = MAX_FRAMES_PER_SEC;
	Xstatic Panel_item framenumber_item, play_item, step_item, eject_item,
	X		xor_rop_item, xor_show_item, frame_item, filename_item,
	X		direction_item, reverse_item, repeat_item, per_sec_item,
	X		clear_item, clipping_item;
	X
	Xstatic void filename_proc ()
	X{
	X	if (current_frame)
	X		(void) panel_set (filename_item,
	X			PANEL_LABEL_STRING, current_frame->filename,
	X			0);
	X}
	X
	Xstatic void direction_proc (item, value, event)
	XPanel_item	item;
	Xunsigned int	value;
	XEvent		*event;
	X{
	X	if (value == BACKWARD)
	X		step = -1;
	X	else if (value == FORWARD)
	X		step = 1;
	X}
	X
	Xstatic void xor_rop_proc (item, value, event)
	XPanel_item	item;
	Xunsigned int	value;
	XEvent		*event;
	X{
	X	/* Use XOR RasterOP ? */
	X	xor_rop = value;
	X}
	X
	Xstatic void xor_show_proc (item, value, event)
	XPanel_item	item;
	Xunsigned int	value;
	XEvent		*event;
	X{
	X	xor_show = value;
	X	if (xor_show)	/* Disable the "XOR_use" button */
	X		(void) panel_set (xor_rop_item, PANEL_SHOW_ITEM, FALSE, 0);
	X	else
	X		(void) panel_set (xor_rop_item, PANEL_SHOW_ITEM, TRUE, 0);
	X	if (current_frame)
	X		(void) display_frame (current_frame);
	X}
	X
	Xstatic void reverse_proc (item, value, event)
	XPanel_item	item;
	Xunsigned int	value;
	XEvent		*event;
	X{
	X	auto_reverse = value;
	X	if (auto_reverse)	/* Disable the "Repeat" button */
	X		(void) panel_set (repeat_item, PANEL_SHOW_ITEM, FALSE, 0);
	X	else
	X		(void) panel_set (repeat_item, PANEL_SHOW_ITEM, TRUE, 0);
	X}
	X
	Xstatic void repeat_proc (item, value, event)
	XPanel_item	item;
	Xunsigned int	value;
	XEvent		*event;
	X{
	X	repeat = value;
	X}
	X
	Xstatic void clipping_proc (item, value, event)
	XPanel_item	item;
	Xunsigned int	value;
	XEvent		*event;
	X{
	X	clipping = value;
	X}
	X
	Xstatic Image *locate_frame (number)
	Xint number;	/* Assumed between 1 and num_images */
	X{
	X	Image *frame;
	X	if (current_number == 0)
	X		(void) next_frame (&current_number);
	X	if (current_frame == (Image *)NULL)
	X		frame = first_frame;
	X	else
	X		frame = current_frame;
	X
	X	while (number > frame->frameno && frame->right != (Image *)NULL)
	X		frame = frame->right;
	X	while (number < frame->frameno && frame->left != (Image *)NULL)
	X		frame = frame->left;
	X	return frame;
	X}
	X
	Xstatic void display_frame (frame)
	XImage *frame;
	X{
	X	int xoff, yoff;
	X	long int op = PIX_SRC;
	X	struct pixrect *pix, *xor, *pr;
	X
	X	(void) panel_set_value (framenumber_item, frame->frameno);
	X
	X	pix = frame->pix;
	X	if (xor_rop || xor_show) {
	X		if (xor_rop && playing && step < 0)
	X			/* When playing backwards, the XOR-pixrect required
	X			 * is the one of the frame to the right */
	X			xor = frame->right->xor;
	X		else
	X			xor = frame->xor;
	X		if (xor != PIXRECT_NULL) {
	X			if (xor_show)
	X				pix = xor;
	X			else if (xor_rop && playing) {
	X				pix = xor;
	X				op = PIX_DST ^ PIX_SRC;	/* XOR operation */
	X			}
	X		}
	X	}
	X
	X	if (zoom && frame->ras_type == RT_STANDARD) {
	X		xoff = (canvas_par.width  - pix->pr_size.x) / 2;
	X		yoff = (canvas_par.height - zoom * pix->pr_size.y) / 2;
	X	} else if (zoom && frame->ras_type == RT_BYTE_ENCODED) {
	X		xoff = (canvas_par.width  - zoom * pix->pr_size.x) / 2;
	X		yoff = (canvas_par.height - zoom * pix->pr_size.y) / 2;
	X	} else {
	X		xoff = (canvas_par.width  - pix->pr_size.x) / 2;
	X		yoff = (canvas_par.height - pix->pr_size.y) / 2;
	X	}
	X	xoff = xoff<0 ? 0 : xoff;
	X	yoff = yoff<0 ? 0 : yoff;
	X
	X	if (! clipping && playing && xoff > 0 && yoff > 0)
	X		op |= PIX_DONTCLIP;		/* Safe to omit clipping */
	X
	X	/* Set colormap */
	X	if (identical_colormaps == FALSE && frame->map) {
	X		(void)pw_putcolormap (canvaspw, 0, CMS_SIZE, frame->map->map[0],
	X			frame->map->map[1], frame->map->map[2]);
	X	}
	X	/* Write pixrect to canvas-pixwin */
	X	(void) my_pw_rop (canvaspw, xoff, yoff,
	X			pix->pr_size.x, pix->pr_size.y, op, pix, 0, 0, zoom);
	X}
	X
	Xstatic void message (msg)
	Xchar *msg;
	X{
	X	if (*msg) {
	X		char text[100];
	X		(void) sprintf (text, "%s - %s", title, msg);
	X		(void) window_set (window_frame, FRAME_LABEL, text, 0);
	X	} else
	X		(void) window_set (window_frame, FRAME_LABEL, title, 0);
	X}
	X
	Xvoid step_proc ()
	X{
	X	(void) message ("");
	X	if (next_frame (&current_number) == FALSE)
	X		return;
	X	current_frame = locate_frame (current_number);
	X	(void) filename_proc ();
	X	(void) display_frame (current_frame);
	X}
	X
	Xstatic void clear_proc ()
	X{
	X	register int color;
	X
	X	if (canvas_par.depth == 1) {		/* Monochrome */
	X		if (background_color)
	X			color = PIX_SET;
	X		else
	X			color = PIX_CLR;
	X	} else {				/* Color */
	X		color = PIX_SRC | PIX_COLOR(background_color);
	X	}
	X
	X	/* Need CANVAS_WIDTH, CANVAS_HEIGHT to clear entire canvas */
	X	(void) pw_writebackground (canvaspw, 0, 0,
	X		canvas_par.canvas_width, canvas_par.canvas_height, color);
	X}
	X
	Xstatic void frame_proc (item, frame, event)
	XPanel_item item;
	Xunsigned int frame;
	Xstruct inputevent *event;
	X{
	X	int tmp = step;
	X	current_number = (int)frame;
	X	step = 0;
	X	(void) step_proc();
	X	step = tmp;
	X}
	X
	Xstatic void per_sec_proc (item, per_sec, event)
	XPanel_item item;
	Xunsigned int per_sec;
	Xstruct inputevent *event;
	X{
	X	frames_per_sec = per_sec;
	X}
	X
	XNotify_value halt_proc ()
	X{
	X	Halt = TRUE;
	X	return (NOTIFY_DONE);
	X}
	X
	Xstatic int next_frame (number)
	Xint *number;
	X{
	X	*number += step;
	X	if (auto_reverse) {
	X		if (*number > num_images) {
	X			*number = num_images - 1;
	X			step = -1;
	X			(void) panel_set_value (direction_item, BACKWARD);
	X		} else if (*number < 1) {
	X			*number = 2;
	X			step = 1;
	X			(void) panel_set_value (direction_item, FORWARD);
	X		}
	X	} else if (repeat) {
	X		if (*number > num_images)
	X			*number = 1;
	X		else if (*number < 1)
	X			*number = num_images;
	X	} else {
	X		if (*number > num_images) {
	X			(void) message ("At end of tape");
	X			*number = num_images;
	X			return FALSE;
	X		} else if (*number < 1) {
	X			(void) message ("At beginning of tape");
	X			*number = 1;
	X			return FALSE;
	X		}
	X	}
	X	return TRUE;
	X}
	X
	X#define UPDATE_FREQUENCY 10
	Xstatic void sleep_awhile (tp0)
	Xstruct timeb *tp0;
	X{
	X	struct timeb tp;
	X	int delta_time, delay;
	X	static int count = 0;
	X	static unsigned fps_sum = 0;
	X	unsigned fps, value;
	X
	X	/* Cannot time any faster because resolution is about 1/50-th second.
	X	 * This means that if frames_per_sec == MAX_FRAMES_PER_SEC,
	X	 * the movie will run as fast as possible */
	X	if (frames_per_sec >= MAX_FRAMES_PER_SEC)
	X		return;
	X	(void) ftime (&tp);
	X	delta_time = (tp.time - tp0->time)*1000 +
	X		(unsigned int) (tp.millitm - tp0->millitm);
	X	delay = 1000 / frames_per_sec - delta_time;
	X	if (delay > 5) {
	X		/* sleep that many microseconds */
	X		(void) usleep ((unsigned)delay*1000);
	X		fps = frames_per_sec;
	X	} else
	X		fps = 1000 / delta_time;
	X	fps_sum += fps;
	X	if (++count % UPDATE_FREQUENCY == 0) {	/* Update at every Nth frame */
	X		value = (unsigned) panel_get (per_sec_item, PANEL_VALUE);
	X		fps = fps_sum / UPDATE_FREQUENCY;
	X		if (fps != value)
	X			(void) panel_set_value (per_sec_item, fps);
	X		fps_sum = 0;
	X	}
	X}
	X
	Xstatic short hglass_array[] = {
	X#include <images/hglass.cursor>
	X};
	Xmpr_static (hglass, 16, 16, 1, hglass_array);
	Xstatic Cursor hourglass = (Cursor)NULL, pointer = (Cursor)NULL;
	X
	Xstatic void play_proc ()
	X{
	X	int next = TRUE;
	X	struct timeb tp;
	X	extern Notify_error notify_dispatch ();
	X	char handle[10];
	X	Rect *rect;	/* For locking */
	X
	X	(void) sprintf (handle, "%d", getpid ());
	X	(void) notify_set_signal_func (handle, halt_proc, SIGURG, NOTIFY_ASYNC);
	X	/* Enable a repeat, even if at beginning/end of tape,
	X	 * when "Play" is pressed again */
	X	if (! auto_reverse && ! repeat) {
	X		if (current_number + step > num_images)
	X			current_number = 1;
	X		else if (current_number + step < 1)
	X			current_number = num_images;
	X	}
	X	Halt = FALSE;
	X	(void) message ("Press Stop/L1 to interrupt");
	X	(void) panel_set (filename_item, PANEL_SHOW_ITEM, FALSE, 0);
	X	current_frame = locate_frame (current_number);
	X	(void) window_set (canvas,	/* Disable retained canvas */
	X		CANVAS_RETAINED, FALSE,
	X		CANVAS_AUTO_CLEAR, FALSE,
	X		0);
	X	rect = (Rect *) window_get(canvas, WIN_RECT);
	X	if (! hourglass)
	X		hourglass = cursor_create (CURSOR_IMAGE, &hglass, 0);
	X	if (! pointer)
	X		pointer = cursor_copy (window_get (panel, WIN_CURSOR));
	X	(void) window_set (panel, WIN_CURSOR, hourglass, 0);
	X	/* (void) clear_proc(); /* Only if desired */
	X	(void) ftime (&tp);	/* Timing */
	X	if (! xor_rop)	/* Double buffering does not work with XOR */
	X		(void) pw_dbl_access (canvaspw);	/* Double buffering */
	X
	X	/* Main display loop */
	X
	X	playing = TRUE;
	X	while (! Halt) {
	X		(void) pw_lock (canvaspw, rect);
	X		(void) display_frame (current_frame);
	X		if (! xor_rop)
	X			(void) pw_dbl_flip (canvaspw);
	X		(void) pw_unlock (canvaspw); if (Halt) break;
	X		if ((next=next_frame (&current_number)) == FALSE || Halt) break;
	X		current_frame = locate_frame (current_number); if (Halt) break;
	X		(void) sleep_awhile (&tp); if (Halt) break;
	X		(void) ftime (&tp);
	X	}
	X
	X	if (! xor_rop)		/* Release double buffer */
	X		(void) pw_dbl_release (canvaspw);
	X	current_frame = locate_frame (current_number);
	X	/* Enable retained canvas */
	X	(void) window_set (canvas, CANVAS_RETAINED, TRUE, 0);
	X	(void) display_frame (current_frame);
	X	(void) window_set (panel, WIN_CURSOR, pointer, 0);
	X	(void) panel_set_value (per_sec_item, frames_per_sec);
	X	(void) panel_set (filename_item, PANEL_SHOW_ITEM, TRUE, 0);
	X	(void) filename_proc ();
	X	if (next == TRUE)
	X		(void) message ("");
	X	playing = FALSE;
	X}
	X
	Xstatic void eject_proc ()
	X{
	X	if (num_images <= 1 ||
	X		alert_prompt ( (Frame)window_frame, (Event *)NULL,
	X		ALERT_MESSAGE_STRINGS, "Eject the tape and exit Movietool ?", 0,
	X		ALERT_BUTTON_YES,	"Yes",
	X		ALERT_BUTTON_NO,	"Continue", 0)
	X			== ALERT_YES) {
	X		(void) window_set (window_frame,
	X			FRAME_NO_CONFIRM, TRUE, 0);
	X		(void) window_destroy (window_frame);
	X	}
	X}
	X
	Xvoid canvas_repaint_proc (can, pw, r)
	XCanvas can;
	XPixwin *pw;
	XRectlist *r;
	X{
	X	/* Update width and height */
	X	canvas_par.width  = (int) window_get (canvas, WIN_WIDTH);
	X	canvas_par.height = (int) window_get (canvas, WIN_HEIGHT);
	X	canvas_par.canvas_width  = (int) window_get (canvas, CANVAS_WIDTH);
	X	canvas_par.canvas_height = (int) window_get (canvas, CANVAS_HEIGHT);
	X
	X	(void) clear_proc();
	X	if (current_frame)
	X		(void) display_frame (current_frame);
	X}
	X
	Xstatic short on_array[] = {
	X#include <images/on.pr>
	X};
	Xmpr_static (on, 64, 16, 1, on_array);
	X
	Xstatic short off_array[] = {
	X#include <images/off.pr>
	X};
	Xmpr_static (off, 64, 16, 1, off_array);
	X
	Xvoid create_panel_items ()
	X{
	X	int slider_width;
	X
	X	if (num_images <= 1)	/* 1 frame - no fancy stuff needed */
	X		return;
	X
	X	eject_item = panel_create_item (panel, PANEL_BUTTON,
	X		PANEL_ITEM_X, ATTR_COLS(25),
	X		PANEL_ITEM_Y, ATTR_ROWS(1)-9,
	X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Eject", 5, 0),
	X		PANEL_NOTIFY_PROC, eject_proc,
	X		0);
	X
	X	play_item = panel_create_item (panel, PANEL_BUTTON,
	X		PANEL_ITEM_X, ATTR_COLS(1),
	X		PANEL_ITEM_Y, ATTR_ROWS(1)-9,
	X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Play", 5, 0),
	X		PANEL_NOTIFY_PROC, play_proc,
	X		0);
	X
	X	step_item = panel_create_item (panel, PANEL_BUTTON,
	X		PANEL_ITEM_X, ATTR_COLS(9),
	X		PANEL_ITEM_Y, ATTR_ROWS(1)-9,
	X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Step", 5, 0),
	X		PANEL_NOTIFY_PROC, step_proc,
	X		0);
	X
	X	clear_item = panel_create_item (panel, PANEL_BUTTON,
	X		PANEL_ITEM_X, ATTR_COLS(17),
	X		PANEL_ITEM_Y, ATTR_ROWS(1)-9,
	X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Clear", 5, 0),
	X		PANEL_NOTIFY_PROC, clear_proc,
	X		0);
	X
	X	if (xor_flag) {
	X		xor_rop = TRUE;
	X		xor_show_item = panel_create_item (panel, PANEL_CYCLE,
	X			PANEL_ITEM_X, ATTR_COLS(40),
	X			PANEL_ITEM_Y, ATTR_ROWS(1)-14,
	X			PANEL_LABEL_STRING, "Image:",
	X			PANEL_MARK_IMAGES, 0,
	X			PANEL_NOMARK_IMAGES, 0,
	X			PANEL_VALUE, 0,
	X			PANEL_CHOICE_STRINGS, "Regular", "XORed", 0,
	X			PANEL_NOTIFY_PROC, xor_show_proc,
	X			0);
	X
	X		xor_rop_item = panel_create_item (panel, PANEL_CYCLE,
	X			PANEL_ITEM_X, ATTR_COLS(40),
	X			PANEL_ITEM_Y, ATTR_ROWS(1),
	X			PANEL_LABEL_STRING, "XOR Play",
	X			PANEL_CHOICE_IMAGES, &off, &on, 0,
	X			PANEL_MARK_IMAGES, 0,
	X			PANEL_NOMARK_IMAGES, 0,
	X			PANEL_VALUE, xor_rop,
	X			PANEL_NOTIFY_PROC, xor_rop_proc,
	X			0);
	X	}
	X	/* frame number display for the current image on show */
	X	if (num_images < 10)
	X		slider_width = 20;
	X	else if (num_images > 100)
	X		slider_width = 200;
	X	else
	X		slider_width = 2 * num_images;
	X
	X	framenumber_item = panel_create_item (panel, PANEL_SLIDER,
	X		PANEL_ITEM_X, ATTR_COLS(1),
	X		PANEL_ITEM_Y, ATTR_ROWS(2),
	X		PANEL_NOTIFY_LEVEL, PANEL_DONE,
	X		PANEL_LABEL_STRING, "Frame:",
	X		PANEL_SLIDER_WIDTH, slider_width,
	X		PANEL_VALUE, 1,
	X		PANEL_MIN_VALUE, 1,
	X		PANEL_MAX_VALUE, num_images,
	X		PANEL_SHOW_VALUE, TRUE,
	X		PANEL_NOTIFY_PROC, frame_proc,
	X		0);
	X
	X	filename_item = panel_create_item (panel, PANEL_MESSAGE,
	X		PANEL_ITEM_X, ATTR_COLS(24)+slider_width,
	X		PANEL_ITEM_Y, ATTR_ROWS(2),
	X		PANEL_NOTIFY_LEVEL, PANEL_DONE,
	X		PANEL_SHOW_VALUE, TRUE,
	X		PANEL_NOTIFY_PROC, filename_proc,
	X		0);
	X
	X	direction_item = panel_create_item (panel, PANEL_CYCLE,
	X		PANEL_ITEM_X, ATTR_COLS(1),
	X		PANEL_ITEM_Y, ATTR_ROWS(3),
	X		PANEL_LABEL_STRING, "Direction:",
	X		PANEL_VALUE, 0,
	X		PANEL_MARK_IMAGES, 0,
	X		PANEL_NOMARK_IMAGES, 0,
	X		PANEL_CHOICE_STRINGS, "Forward", "Backward", 0,
	X		PANEL_NOTIFY_PROC, direction_proc,
	X		0);
	X
	X	reverse_item = panel_create_item (panel, PANEL_CYCLE,
	X		PANEL_ITEM_X, ATTR_COLS(1),
	X		PANEL_ITEM_Y, ATTR_ROWS(4),
	X		PANEL_LABEL_STRING, "Auto-reverse",
	X		PANEL_VALUE, 0,
	X		PANEL_CHOICE_IMAGES, &off, &on, 0,
	X		PANEL_MARK_IMAGES, 0,
	X		PANEL_NOMARK_IMAGES, 0,
	X		PANEL_SHOW_MENU, FALSE,
	X		PANEL_NOTIFY_PROC, reverse_proc,
	X		0);
	X
	X	repeat_item = panel_create_item (panel, PANEL_CYCLE,
	X		PANEL_ITEM_X, ATTR_COLS(24),
	X		PANEL_ITEM_Y, ATTR_ROWS(4),
	X		PANEL_LABEL_STRING, "Repeat",
	X		PANEL_VALUE, 0,
	X		PANEL_CHOICE_IMAGES, &off, &on, 0,
	X		PANEL_MARK_IMAGES, 0,
	X		PANEL_NOMARK_IMAGES, 0,
	X		PANEL_SHOW_MENU, FALSE,
	X		PANEL_NOTIFY_PROC, repeat_proc,
	X		0);
	X
	X	clipping_item = panel_create_item (panel, PANEL_CYCLE,
	X		PANEL_ITEM_X, ATTR_COLS(41),
	X		PANEL_ITEM_Y, ATTR_ROWS(4),
	X		PANEL_LABEL_STRING, "Clipping",
	X		PANEL_VALUE, 1,
	X		PANEL_CHOICE_IMAGES, &off, &on, 0,
	X		PANEL_MARK_IMAGES, 0,
	X		PANEL_NOMARK_IMAGES, 0,
	X		PANEL_SHOW_MENU, FALSE,
	X		PANEL_NOTIFY_PROC, clipping_proc,
	X		0);
	X
	X	per_sec_item = panel_create_item (panel, PANEL_SLIDER,
	X		PANEL_ITEM_X, ATTR_COLS(1),
	X		PANEL_ITEM_Y, ATTR_ROWS(5) + 6,
	X		PANEL_NOTIFY_LEVEL, PANEL_DONE,
	X		PANEL_LABEL_STRING, "Frames/sec:",
	X		PANEL_SLIDER_WIDTH, 100,
	X		PANEL_VALUE, MAX_FRAMES_PER_SEC,
	X		PANEL_MIN_VALUE, 1,
	X		PANEL_MAX_VALUE, MAX_FRAMES_PER_SEC,
	X		PANEL_SHOW_VALUE, TRUE,
	X		PANEL_NOTIFY_PROC, per_sec_proc,
	X		0);
	X}
SHAR_EOF
if test 15813 -ne "`wc -c < 'movietool.c'`"
then
	echo shar: error transmitting "'movietool.c'" '(should have been 15813 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'paneledit.c'" '(7478 characters)'
if test -f 'paneledit.c'
then
	echo shar: will not over-write existing file "'paneledit.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'paneledit.c'
	X/* $Id: paneledit.c,v 1.0 89/10/01 17:00:29 mbp Exp $
	X *
	X * paneledit.c               version 1.0             February 2, 1989
	X *
	X * Allows dynamic repositioning of all panel items in all panels
	X *
	X * Authors:
	X *                                      procedure move_item() by:
	X *     Mark Phillips                    Chuck Musciano
	X *     Department of Mathematics        Advanced Technology Department
	X *     University of Maryland           Harris Corporation
	X *     College Park, Maryland 20742     PO Box 37, MS 3A/1912
	X *     (301) 454-2693                   Melbourne, FL 32902
	X *     ARPA: mbp@lakisis.umd.edu        (407) 727-6131
	X *                                      ARPA: chuck@trantor.harris-atd.com
	X *
	X * Everything except procedure "move_item":
	X *      Copyright 1989 by Mark Phillips and the University of Maryland
	X *
	X * Procedure "move_item":
	X *      Copyright 1988 by Chuck Musciano and Harris Corporation
	X *
	X * Permission to use, copy, modify, and  distribute this software and
	X * its  documentation for  any purpose   and without   fee is  hereby
	X * granted, provided that  the above copyright  notices appear in all
	X * copies and that both  those  copyright notices and this permission
	X * notice appear in supporting  documentation, and  that the names of
	X * Mark Phillips, the  University  of Maryland,  Chuck Musciano,  and
	X * Harris  Corporation  not be   used  in advertising   or  publicity
	X * pertaining  to   distribution of   the software without  specific,
	X * written prior   permission.   Mark Phillips,   the   University of
	X * Maryland,  Chuck   Musciano,   and  Harris  Corporation  make   no
	X * representations about the  suitability  of  this software  for any
	X * purpose.   It is  provided  "as  is" without  express   or implied
	X * warranty.
	X */
	X
	X#include <stdio.h>
	X#include <suntool/sunview.h>
	X#include <suntool/panel.h>
	X
	Xtypedef	struct save_block_tag {
	X  caddr_t	client_data;
	X  caddr_t	event_proc;
	X} Save_block;
	X
	Xstatic Frame base_frame;
	Xstatic Frame edit_frame;
	Xstatic Panel edit_panel;
	Xstatic Panel_item edit_cycle;
	Xstatic int toggle_edit(), move_item();
	X
	X#define		NO_DRAG		0
	X#define		DRAG_X		1
	X#define		DRAG_Y		2
	Xstatic int dragging = NO_DRAG;
	X
	Xstatic int editing = 0;
	X
	X/*-----------------------------------------------------------------------
	X * Function:	paneledit_init
	X * Description:	Set up editing of SunView panels
	X * Args  IN:	frame: handle of frame
	X * Returns:	success status: 0 for success, 1 for failure
	X * Notes:	All panel items in all subwindows of frame can be edited.
	X */
	Xpaneledit_init(frame)
	XFrame frame;
	X{
	X  int h;
	X
	X  base_frame = frame;
	X
	X  edit_frame =
	X    window_create(base_frame, FRAME,
	X		  FRAME_LABEL, "paneledit - 1.0",
	X		  FRAME_SHOW_LABEL, TRUE,
	X		  0);
	X
	X  edit_panel = window_create(edit_frame, PANEL,0);
	X  edit_cycle =
	X    panel_create_item(edit_panel, PANEL_CYCLE,
	X		      PANEL_LABEL_STRING, "Panel Editing ",
	X		      PANEL_CHOICE_STRINGS, "Off", "On", 0,
	X		      PANEL_NOTIFY_PROC, toggle_edit,
	X		      0);
	X  window_fit(edit_panel);
	X  window_fit(edit_frame);
	X  window_set(edit_frame,
	X/*
	X	     WIN_X, (int)window_get(base_frame, WIN_WIDTH),
	X	     WIN_Y, 0,
	X*/
	X	     WIN_SHOW, TRUE,
	X	     0);
	X}
	X
	X/*-----------------------------------------------------------------------
	X * Function:	toggle_edit
	X * Description:	toggle whether panel items are being edited
	X * Notes:	this is the event procedure for the editing cycle item
	X */
	Xstatic int
	Xtoggle_edit()
	X{
	X  /* We toggle the editing state and apply new state to window tree */
	X  editing = !editing;
	X  set_editing_in_window(base_frame, editing);
	X}
	X
	X/*-----------------------------------------------------------------------
	X * Function:	set_editing_in_window
	X * Description:	turn editing on or off in a specific window
	X * Args  IN:	window: the window's handle
	X *		edit: 0 to turn editing off, 1 to turn it on
	X * Returns:	nothing
	X * Notes:	This procedure calls itself to operate on the entire
	X *		window tree with window as root
	X */
	Xstatic int
	Xset_editing_in_window(window, edit)
	X     Window window;
	X     int edit;
	X{
	X  int winno;
	X  Window subwindow;
	X
	X  winno = 0;
	X  do {
	X    /* Get next subwindow */
	X    subwindow = (Window)window_get(window, FRAME_NTH_WINDOW, winno);
	X    if (subwindow!=NULL) {
	X      /* Make sure this is not the edit frame! */
	X      if (subwindow != edit_frame) {
	X	switch ( (Window_type)(window_get(subwindow,WIN_TYPE)) ) {
	X	case FRAME_TYPE:
	X	  set_editing_in_window(subwindow, edit);
	X	  break;
	X	case PANEL_TYPE:
	X	  set_editing_in_panel(subwindow, edit);
	X	  break;
	X	default:
	X	  /* do nothing */
	X	  break;
	X	}
	X      }
	X    }
	X    ++winno;
	X  } while (subwindow != NULL);
	X}
	X
	X/*-----------------------------------------------------------------------
	X * Function:	set_editing_in_panel
	X * Description:	turn editing on or off for all items in a panel
	X * Args  IN:	panel: the panel's handle
	X *		edit: 0 to turn editing off, 1 to turn it on
	X * Returns:	nothing
	X */
	Xstatic int
	Xset_editing_in_panel(panel, edit)
	X     Panel panel;
	X     int edit;
	X{
	X  Panel_item item;
	X  Save_block *b;
	X
	X  /* Loop thru each item in this panel */
	X  panel_each_item(panel, item) {
	X
	X    if (edit) {
	X
	X      /* allocate a Save_block for item's current info */
	X      b = (Save_block*)malloc(sizeof(Save_block));
	X      if (b == NULL) {
	X	printf(stderr, "Sorry, no memory left for panel_edit !!\n");
	X	exit(1);
	X      }
	X      b->client_data = (caddr_t)panel_get(item, PANEL_CLIENT_DATA);
	X      b->event_proc = (caddr_t)panel_get(item, PANEL_EVENT_PROC);
	X
	X      /* Store pointer to this Save_block as item's new client data */
	X      panel_set(item, PANEL_CLIENT_DATA, b, 0);
	X
	X      /* For editing, use move_item as event proc */
	X      panel_set(item, PANEL_EVENT_PROC, move_item, 0);
	X    }
	X
	X    else {
	X
	X      /* restore previous event proc and client data */
	X      b = (Save_block*)panel_get(item, PANEL_CLIENT_DATA);
	X      panel_set(item, PANEL_EVENT_PROC, b->event_proc, 0);
	X      panel_set(item, PANEL_CLIENT_DATA, b->client_data, 0);
	X
	X      /* free up the Save_block */
	X      free(b);
	X    }
	X
	X  } panel_end_each;
	X
	X}
	X
	X/*-----------------------------------------------------------------------
	X * Function:	move_item
	X * Description:	A notify proc which allows items to move about and then
	X *		  report their position.
	X * Args  IN:	item: item's handle
	X *		event: event which caused notification
	X * Returns:	nothing
	X * Notes: 	Copyright 1988 by Chuck Musciano and Harris Corporation
	X */
	Xstatic int
	Xmove_item(item, event)
	X     Panel_item	item;
	X     Event	*event;
	X{
	X  static int old_x, old_y;
	X  static Panel_item old_item;
	X
	X  if (event_id(event) == MS_LEFT)
	X    if (event_is_down(event)) {
	X      dragging = DRAG_X;
	X      old_x = event_x(event);
	X      old_item = item;
	X    }
	X    else
	X      dragging = NO_DRAG;
	X  else if (event_id(event) == MS_MIDDLE)
	X    if (event_is_down(event)) {
	X      dragging = DRAG_Y;
	X      old_y = event_y(event);
	X      old_item = item;
	X    }
	X    else
	X      dragging = NO_DRAG;
	X  else if (event_id(event) == MS_RIGHT && event_is_down(event))
	X    printf("%5d %5d\n", panel_get(item, PANEL_ITEM_X),
	X	   panel_get(item, PANEL_ITEM_Y));
	X  else if (event_id(event) == LOC_DRAG)
	X    if (dragging == DRAG_X) {
	X      panel_set(old_item, PANEL_ITEM_X,
	X		panel_get(item, PANEL_ITEM_X) + event_x(event) - old_x, 0);
	X      old_x = event_x(event);
	X    }
	X    else if (dragging == DRAG_Y) {
	X      panel_set(old_item, PANEL_ITEM_Y,
	X		panel_get(item, PANEL_ITEM_Y) + event_y(event) - old_y, 0);
	X      old_y = event_y(event);
	X    }
	X    else
	X      panel_default_handle_event(item, event);
	X}
SHAR_EOF
if test 7478 -ne "`wc -c < 'paneledit.c'`"
then
	echo shar: error transmitting "'paneledit.c'" '(should have been 7478 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pr_decode.c'" '(4907 characters)'
if test -f 'pr_decode.c'
then
	echo shar: will not over-write existing file "'pr_decode.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'pr_decode.c'
	X/*
	X * This file is part of
	X * Movietool: display a succession of rasterfile frames in real-time
	X *
	X * Copyright 1989, 1990 by Ole H. Nielsen
	X *
	X * Author: Ole H. Nielsen
	X *         Lab of Applied Physics, Bygn. 307
	X *         Technical University of Denmark, DK-2800 Lyngby
	X *         E-mail: ohnielse@ltf.dth.dk
	X */
	X
	X#include <stdio.h>
	X#include <memory.h>
	X#include <pixrect/pixrect_hs.h>
	X
	X/* The byte-encoded data format is as follows (Pixrect Ref. Manual p.59):
	X *	0x80 is used as a flag to introduce run-length encoded data
	X *	<0x80> <rept> <value>	represents rept+1 occurrences of <value>
	X *	<0x80> <0>	 	represents a single occurrence of <0x80>
	X *	<0x80> <1> <0x80> 	represents <0x80> <0x80>
	X *	All other values	represent unencoded data
	X * It is only worth encoding repetitions of 3 or more, except if the
	X * value is <0x80> which must always be encoded.
	X * Note that memory-pixrect lines must be aligned on 32-bit boundaries,
	X * and that a repeated value (above) may cross one or more line boundaries.
	X */
	X
	X#define FLAG 0x80
	X
	Xint pr_decode (dpr, xoff, yoff, spr)
	Xstruct pixrect *dpr, *spr;
	Xint xoff, yoff;		/* Offsets */
	X{
	X	register u_char *buf;		/* Input data buffer */
	X	register u_char *image;		/* Pointer to image data */
	X	register u_char ch;
	X	register short w, count;
	X	register short bw, h, padding, pending = 0;
	X	short line;
	X	u_char *lastbyte;
	X	struct mpr_data *data;
	X 
	X	if (spr->pr_depth != dpr->pr_depth)
	X		return (PIX_ERR);
	X
	X	/* Input buffer of RT_BYTE_ENCODED data (My private definition) */
	X	buf = (u_char *) spr->pr_data;
	X	data = mpr_d(dpr);
	X	image = mprd8_addr (data, xoff, yoff, dpr->pr_depth);
	X	lastbyte = mprd8_addr(data, dpr->pr_size.x, dpr->pr_size.y,
	X		dpr->pr_depth);
	X	/* Byte width of a line.
	X	 * Note that rasterfiles contain short (16-bit) words of image data.
	X	 * (see /usr/include/rasterfile.h) */
	X	bw = ((spr->pr_depth * spr->pr_size.x + 15) / 16) * 2;
	X	h = (short)spr->pr_size.y;
	X 
	X	padding = data->md_linebytes - bw;
	X	w = 0;
	X
	X	/* Big loop over rasterfile lines */
	X
	X	for (line=0; line<h; line++) {
	X		if (pending > 0) {
	X			if (pending > bw) {
	X				count = bw;
	X				pending -= bw;
	X			} else {
	X				count = pending;
	X				pending = 0;
	X			}
	X			(void) memset (image, *(buf-1), count);
	X			image += count;
	X		}
	X		w += bw;
	X
	X		while (w > 0) {
	X			w--;
	X			if (*buf == FLAG) {
	X				/* Count 0 means FLAG */
	X				if ((count = *(++buf)) != 0) {
	X					buf++;
	X					/* count+1 of ch */
	X					w -= count;
	X					if (w < 0) {
	X						pending = - w;
	X						count -= pending;
	X					}
	X					count++;
	X					(void) memset (image, *buf, count);
	X					image += count;
	X				} else
	X					*image++ = FLAG;
	X			} else
	X				*image++ = *buf;
	X			buf++;
	X		}
	X		image += padding;		/* Apply padding */
	X		if (image >= lastbyte)		/* Clip at end of dpr */
	X			break;
	X	}
	X	return (0);
	X}
	X
	Xint pr_decode_and_zoom (dpr, xoff, yoff, spr, zoom)
	Xstruct pixrect *dpr, *spr;
	Xint xoff, yoff;		/* Offsets */
	Xint zoom;		/* Zoom factor */
	X{
	X	register u_char *buf;		/* Input data buffer */
	X	register u_char *image;		/* Pointer to image data */
	X	register u_char ch;
	X	register short w, count;
	X	register short bw, h, padding, pending = 0;
	X	short line;
	X	u_char *lastbyte, *line_start;
	X	struct mpr_data *data;
	X 
	X	if (zoom < 2 || spr->pr_depth != dpr->pr_depth)
	X		return (PIX_ERR);
	X
	X	/* Input buffer of RT_BYTE_ENCODED data (My private definition) */
	X	buf = (u_char *) spr->pr_data;
	X	data = mpr_d(dpr);
	X	image = mprd8_addr (data, xoff, yoff, dpr->pr_depth);
	X	lastbyte = mprd8_addr(data, dpr->pr_size.x, dpr->pr_size.y,
	X		dpr->pr_depth);
	X	/* Byte width of a line.
	X	 * Note that rasterfiles contain short (16-bit) words of image data.
	X	 * (see /usr/include/rasterfile.h) */
	X	bw = zoom * ((spr->pr_depth * spr->pr_size.x + 15) / 16) * 2;
	X	h = (short)spr->pr_size.y;
	X 
	X	padding = data->md_linebytes - bw;
	X	w = 0;
	X
	X	/* Big loop over rasterfile lines */
	X
	X	for (line=0; line<h; line++) {
	X		line_start = image;
	X		if (pending > 0) {
	X			if (pending > bw) {
	X				count = bw;
	X				pending -= bw;
	X			} else {
	X				count = pending;
	X				pending = 0;
	X			}
	X			(void) memset (image, *(buf-1), count);
	X			image += count;
	X		}
	X		w += bw;
	X
	X		while (w > 0) {
	X			w -= zoom;
	X			if (*buf == FLAG) {
	X				/* Count 0 means FLAG */
	X				if ((count = *(++buf)) != 0) {
	X					buf++;
	X					/* count+1 of ch */
	X					count *= zoom;
	X					w -= count;
	X					if (w < 0) {
	X						pending = - w;
	X						count -= pending;
	X					}
	X					count += zoom;
	X					(void) memset (image, *buf, count);
	X					image += count;
	X				} else {
	X					(void) memset (image, FLAG, zoom);
	X					image += zoom;
	X				}
	X			} else {
	X				(void) memset (image, *buf, zoom);
	X				image += zoom;
	X			}
	X			buf++;
	X		}
	X		image += padding;		/* Apply padding */
	X		if (image >= lastbyte)		/* Clip at end of dpr */
	X			break;
	X
	X		/* Zoom in the y-direction */
	X		for (count = 1; count < zoom; count++) {
	X			memcpy (image, line_start, bw);
	X			image += data->md_linebytes;
	X			if (image >= lastbyte) break;
	X		}
	X		if (image >= lastbyte) break;
	X	}
	X	return (0);
	X}
SHAR_EOF
if test 4907 -ne "`wc -c < 'pr_decode.c'`"
then
	echo shar: error transmitting "'pr_decode.c'" '(should have been 4907 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pr_load.c'" '(5580 characters)'
if test -f 'pr_load.c'
then
	echo shar: will not over-write existing file "'pr_load.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'pr_load.c'
	X/*
	X * This file is part of
	X * Movietool: display a succession of rasterfile frames in real-time
	X *
	X * Copyright 1989, 1990 by Ole H. Nielsen
	X *
	X * Author: Ole H. Nielsen
	X *         Lab of Applied Physics, Bygn. 307
	X *         Technical University of Denmark, DK-2800 Lyngby
	X *         E-mail: ohnielse@ltf.dth.dk
	X */
	X
	X#include <stdio.h>
	X#include <pixrect/pixrect_hs.h>
	X 
	Xint pr_load_header (input, rh)
	XFILE *input;			/* Input file */
	Xstruct rasterfile *rh;		/* Rasterfile header */
	X{
	X 
	X	/* Read and check file header   */
	X 
	X	if (fread(rh, sizeof(*rh), 1, input) != 1)
	X		return (PIX_ERR);
	X	if (rh->ras_magic != RAS_MAGIC)
	X		return (PIX_ERR);
	X	return (0);
	X}
	X 
	Xint pr_load_colormap (input, rh, colormap)
	XFILE *input;				/* Input file */
	Xstruct rasterfile *rh;			/* Rasterfile header */
	Xcolormap_t *colormap;			/* Optional colourmap */
	X{
	X	int len;
	X 
	X	/* Load (or skip) colormap	*/
	X 
	X	if (colormap == NULL)
	X		fseek(input, rh->ras_maplength, 1);	/* skip map */
	X	else {
	X		colormap->type	= rh->ras_maptype;
	X		if (rh->ras_maptype == RMT_EQUAL_RGB) {
	X			/* Pixrect Reference Manual p. 62, 66:
	X			 * If colormap is non-NULL, colormap is read in.
	X			 * pr_load_colormap will allocate space for colormap
	X			 * if it does not match that of the file. */
	X			len = rh->ras_maplength;
	X			if (colormap->length < len / 3) {
	X				colormap->length = len / 3;
	X				if ((colormap->map[0] = (u_char *)malloc (len))
	X					== NULL)
	X					return (PIX_ERR);
	X				colormap->map[1] = colormap->map[0] + len / 3;
	X				colormap->map[2] = colormap->map[1] + len / 3;
	X			}
	X			fread(colormap->map[0], colormap->length, 1, input);
	X			fread(colormap->map[1], colormap->length, 1, input);
	X			fread(colormap->map[2], colormap->length, 1, input);
	X		} else
	X			fseek(input, rh->ras_maplength, 1); /*skip map*/
	X	}
	X	return (0);
	X}
	X 
	X/* The byte-encoded data format is as follows (Pixrect Ref. Manual p.59):
	X *	0x80 is used as a flag to introduce run-length encoded data
	X *	<0x80> <rept> <value>	represents rept+1 occurrences of <value>
	X *	<0x80> <0>	 	represents a single occurrence of <0x80>
	X *	<0x80> <1> <0x80> 	represents <0x80> <0x80>
	X *	All other values	represent unencoded data
	X * It is only worth encoding repetitions of 3 or more, except if the
	X * value is <0x80> which must always be encoded.
	X * Note that memory-pixrect lines must be aligned on 32-bit boundaries,
	X * and that a repeated value (above) may cross line boundaries.
	X */
	X 
	X#define FLAG 0x80
	X#define PIXRECT_NULL (struct pixrect *)NULL
	X
	Xstruct pixrect *pr_load_image (input, rh, colormap)
	Xregister FILE *input;			/* Input file */
	Xstruct rasterfile *rh;			/* Rasterfile header */
	Xcolormap_t *colormap;			/* Optional colourmap */
	X{
	X	register char	*image;		/* Pointer to image data */
	X	register int	ch;		/* Input data character */
	X	register short	w, bw, h, count, padding, pending=0;
	X	struct pixrect	*pr;		/* Output pixrect */
	X	struct mpr_data	*data;		/* Pixrect data */
	X 
	X	/* Create pixrect and load data */
	X	/* We must take care because of the 32-bit line padding
	X	 * in a memory pixrect (See Pixrect Reference Manual p. 53) */
	X 
	X	if ((pr = mem_create (rh->ras_width,
	X		rh->ras_height, rh->ras_depth)) == NULL)
	X		return (PIXRECT_NULL);
	X	data = mpr_d(pr);	/* Nice for debugging */
	X	image = (char *) data->md_image;
	X	/* Byte width of a line.
	X	 * Note that rasterfiles contain short (16-bit) words of image data.
	X	 * (see /usr/include/rasterfile.h) */
	X	bw = ((pr->pr_depth * pr->pr_size.x + 15) / 16) * 2;
	X	h = (short)pr->pr_size.y;
	X 
	X	if (rh->ras_type == RT_STANDARD) {
	X		while (h--) {
	X			if (fread(image, bw, 1, input) != 1)
	X				return (PIXRECT_NULL);
	X			image += data->md_linebytes;
	X		}
	X	} else if (rh->ras_type == RT_BYTE_ENCODED) {
	X		padding = data->md_linebytes - bw;
	X		w = 0;
	X		while (h--) {
	X			w += bw;
	X			while (w > 0) {
	X				w--;
	X				if ((ch = getc(input)) == FLAG) {
	X					/* Count 0 means FLAG */
	X					if ((count = getc(input)) != 0) {
	X						ch = getc(input);
	X						/* count+1 of ch */
	X						w -= count;
	X						if (w < 0) {
	X							pending = -w;
	X							count -= pending;
	X						}
	X						while (count--)
	X							*image++ = ch;
	X					}
	X				}
	X				*image++ = ch;
	X			}
	X			image += padding;	/* Apply padding */
	X			if (pending > 0) {
	X				if (pending > bw) {
	X					count = bw;
	X					pending -= bw;
	X				} else {
	X					count = pending;
	X					pending = 0;
	X				}
	X				while (count--)
	X					*image++ = ch;
	X			}
	X		}
	X		if (ch == EOF)
	X			return (PIXRECT_NULL);		/* Check end-of-file */
	X	}
	X
	X	return (pr);
	X}
	X
	X/* Read the RT_BYTE_ENCODED image data without decoding */
	X
	Xstruct pixrect *pr_load_encoded_image (input, rh)
	XFILE *input;
	Xstruct rasterfile *rh;
	X{
	X	struct pixrect *pr;
	X
	X	if (rh->ras_type != RT_BYTE_ENCODED)
	X		return (PIXRECT_NULL);
	X
	X	pr = (struct pixrect *) malloc(sizeof(struct pixrect));
	X	pr->pr_ops	= (struct pixrectops *)NULL;
	X	pr->pr_size.x	= rh->ras_width;
	X	pr->pr_size.y	= rh->ras_height;
	X	pr->pr_depth	= rh->ras_depth;
	X	pr->pr_data	= (caddr_t) malloc(rh->ras_length);
	X	/* Stuff the RT_BYTE_ENCODED image data into the pixrect data area */
	X	if (fread(pr->pr_data, rh->ras_length, 1, input) != 1) {
	X		free (pr->pr_data);
	X		free (pr);
	X		return (PIXRECT_NULL);
	X	}
	X	return (pr);
	X}
	X
	Xstruct pixrect *pr_load(input, colormap)
	XFILE *input;				/* Input file */
	Xcolormap_t *colormap;			/* Optional colourmap */
	X{
	X	struct rasterfile rh;		/* Rasterfile header */
	X 
	X	/* Read and check file header   */
	X 
	X	if (pr_load_header (input, &rh) == PIX_ERR)
	X		return (PIXRECT_NULL);
	X 
	X	/* Load (or skip) colormap	*/
	X 
	X	if (pr_load_colormap (input, &rh, colormap) == PIX_ERR)
	X		return (PIXRECT_NULL);
	X 
	X	/* Create pixrect and load data */
	X 
	X	return (pr_load_image (input, &rh, colormap));
	X}
SHAR_EOF
if test 5580 -ne "`wc -c < 'pr_load.c'`"
then
	echo shar: error transmitting "'pr_load.c'" '(should have been 5580 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pw_rop.c'" '(2276 characters)'
if test -f 'pw_rop.c'
then
	echo shar: will not over-write existing file "'pw_rop.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'pw_rop.c'
	X#include "movietool.h"
	X#include <stdio.h>
	X#include <suntool/canvas.h>
	X#include <suntool/scrollbar.h>
	X
	X/* global declarations */
	X
	Xextern Canvas	canvas;
	Xextern Pixwin	*canvaspw;
	Xextern Image	*current_frame;
	Xextern int	encoded_flag;
	Xextern int	playing;
	Xextern int	clipping;
	X
	Xvoid my_pw_rop (pw, dx, dy, dw, dh, op, pr, sx, sy, zoom)
	XPixwin *pw;
	Xint dx, dy, dw, dh, op, sx, sy, zoom;
	Xstruct pixrect *pr;
	X{
	X	struct pixrect *pr_tmp;
	X	register int y, z;
	X
	X	if (encoded_flag && current_frame->ras_type == RT_BYTE_ENCODED) {
	X		if (! clipping && playing &&
	X			pr->pr_depth == canvaspw->pw_pixrect->pr_depth) {
	X
	X			/* This approach isn't clean since it scribbles directly
	X		 	 * onto the display without any attempt at clipping.
	X		 	 * However, the speed it offers is attractive.
	X		 	 * If you zoom the tool to full-screen size,
	X		 	 * you (hopefully) won't notice the problems. */
	X
	X			/* Add pixwin coordinates relative to screen origin */
	X			dx += canvaspw->pw_clipdata->pwcd_screen_x;
	X			dy += canvaspw->pw_clipdata->pwcd_screen_y;
	X			/* Add scrollbar thickness */
	X			dx += (int) scrollbar_get (window_get
	X				(canvas, WIN_VERTICAL_SCROLLBAR),
	X				SCROLL_THICKNESS);
	X			dy += (int) scrollbar_get (window_get
	X				(canvas, WIN_HORIZONTAL_SCROLLBAR),
	X				SCROLL_THICKNESS);
	X			if (zoom) {
	X				if (pr_decode_and_zoom (canvaspw->pw_pixrect,
	X					dx, dy, pr, zoom) == PIX_ERR)
	X					fprintf(stderr,
	X					"Error in pr_decode_and_zoom\n");
	X			} else {
	X				if (pr_decode (canvaspw->pw_pixrect,
	X					dx, dy, pr) == PIX_ERR)
	X					fprintf(stderr, "Error in pr_decode\n");
	X			}
	X		} else {
	X			/* Copy to intermediate pixrect */
	X			if (zoom) {
	X				pr_tmp = mem_create (pr->pr_size.x * zoom,
	X					pr->pr_size.y * zoom, pr->pr_depth);
	X				(void) pr_decode_and_zoom (pr_tmp, 0, 0, pr,
	X					zoom);
	X				dw *= zoom;
	X				dh *= zoom;
	X			} else {
	X				pr_tmp = mem_create(pr->pr_size.x,
	X					pr->pr_size.y, pr->pr_depth);
	X				(void) pr_decode (pr_tmp, 0, 0, pr);
	X			}
	X			(void) pw_rop (canvaspw, dx, dy, dw, dh,
	X				op, pr_tmp, sx, sy);
	X			pr_close (pr_tmp);
	X		}
	X	} else
	X		if (zoom) {
	X			for (y=0; y<pr->pr_size.y; y++) {
	X				for (z=0; z<zoom; z++) {
	X					(void)pw_rop (canvaspw, dx, z+zoom*y+dy,
	X						dw, 1, op, pr, sx, y+sy);
	X				}
	X			}
	X		} else
	X			(void)pw_rop (canvaspw, dx, dy, dw, dh, op, pr, sx, sy);
	X}
SHAR_EOF
if test 2276 -ne "`wc -c < 'pw_rop.c'`"
then
	echo shar: error transmitting "'pw_rop.c'" '(should have been 2276 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'zoom.c'" '(1060 characters)'
if test -f 'zoom.c'
then
	echo shar: will not over-write existing file "'zoom.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'zoom.c'
	X#include <suntool/sunview.h>
	X
	X#define ROP PIX_SRC | PIX_DONTCLIP
	X#define PIXRECT_NULL (struct pixrect *)NULL
	X
	X/* pr_mag copies a magnified view of spr to dpr using pixel replication  */
	X
	Xstruct pixrect *pr_mag (spr, magx, magy)
	Xstruct pixrect *spr;	/* source pixrect */
	Xint magx, magy;	 	/* x and y magnifications */
	X{
	X	register short xmax = spr->pr_size.x, ymax = spr->pr_size.y - 1;
	X	register short x, y, i, delta;
	X	register struct pixrect *dpr;
	X
	X	if (magx < 1 || magx > 10 || magy < 1 || magy > 10)
	X		return PIXRECT_NULL;
	X
	X	if ((dpr = mem_create (xmax*magx, (ymax+1)*magy, spr->pr_depth)) ==
	X		PIXRECT_NULL)
	X		return PIXRECT_NULL;
	X
	X	if (magx == 1)
	X		pr_rop (dpr, 0, 0, xmax, ymax+1, ROP, spr, 0, 0);
	X	else {
	X		for (x = 0; x < xmax; x++) {
	X			i = x*magx;
	X			for (delta = 0; delta < magx; delta++, i++)
	X				pr_rop (dpr, i, 0, 1, ymax, ROP, spr, x, 0);
	X		}
	X		xmax *= magx;
	X	}
	X
	X	if (magy > 1) {
	X		for (y = ymax; y >= 0; y--) {
	X			i = y*magy;
	X			for (delta = 0; delta < magy; delta++, i++)
	X				pr_rop (dpr, 0, i, xmax, 1, ROP, dpr, 0, y);
	X		}
	X	}
	X
	X	return dpr;
	X}
SHAR_EOF
if test 1060 -ne "`wc -c < 'zoom.c'`"
then
	echo shar: error transmitting "'zoom.c'" '(should have been 1060 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'movietool.h'" '(917 characters)'
if test -f 'movietool.h'
then
	echo shar: will not over-write existing file "'movietool.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'movietool.h'
	X#include <suntool/sunview.h>
	X#define PIXRECT_NULL (Pixrect *)NULL
	X#define CMS_SIZE 256	/* Colormap segment size */
	X
	Xtypedef struct image {
	X	int frameno;		/* Frame's sequence number */
	X	char *filename;		/* Name of file containing image */
	X	struct pixrect *pix;	/* The basic picture */
	X	struct pixrect *xor;	/* The XOR of previous and this picture */
	X	int ras_type;		/* As in rasterfile(5): RT_BYTE_ENCODED ? */
	X	struct image *left;	/* Points left */
	X	struct image *right;	/* Points right */
	X	colormap_t *map;	/* Frame's colormap */
	X} Image;
	X
	Xtypedef struct {	/* Canvas parameters */
	X	/* WIN_* attributes */
	X	int width;		/* Width  of region displayed within window */
	X	int height;		/* Height of region displayed within window */
	X	int depth;		/* Depth  of canvas (1 or 8 bits) */
	X	/* CANVAS_* attributes */
	X	int canvas_width;	/* Width  of entire canvas */
	X	int canvas_height;	/* Height of entire canvas */
	X} Canvas_par;
SHAR_EOF
if test 917 -ne "`wc -c < 'movietool.h'`"
then
	echo shar: error transmitting "'movietool.h'" '(should have been 917 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'INSTALLATION'" '(688 characters)'
if test -f 'INSTALLATION'
then
	echo shar: will not over-write existing file "'INSTALLATION'"
else
sed 's/^	X//' << \SHAR_EOF > 'INSTALLATION'
	XYou want to check Makefile for the definitions of AUDIOPLAYER and AUDIODIR.
	XBy default, the file "movietool.au" in AUDIODIR is played by means of the
	Xprogram AUDIOPLAYER.  A file play.c from the net has been included as a 
	Xconvenient AUDIOPLAYER.  You may use a soft link for "movietool.au" if
	Xyou want flexibility in which file to play.  In case your system doesn't
	Xhave a speaker, simply comment out the lines defining AUDIOPLAYER and AUDIODIR
	Xin Makefile.
	X
	XAlso check the definitions of BINDIR, MANDIR and MANEXT before you install.
	X
	XSay "make install", and you are all set.
	X
	XFor testing, you may obtain the raster file sequence that was posted with
	XMovietool-1.0 from titan.rice.edu.
SHAR_EOF
if test 688 -ne "`wc -c < 'INSTALLATION'`"
then
	echo shar: error transmitting "'INSTALLATION'" '(should have been 688 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'movietool.icon'" '(1933 characters)'
if test -f 'movietool.icon'
then
	echo shar: will not over-write existing file "'movietool.icon'"
else
sed 's/^	X//' << \SHAR_EOF > 'movietool.icon'
	X/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
	X */
	X	0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0003,
	X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0003,
	X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0003,
	X	0xC042,0x0000,0x4000,0x0003,0xC042,0x0000,0x0000,0x0003,
	X	0xC066,0x3889,0xC1C0,0x0003,0xC066,0x4488,0x4220,0x0003,
	X	0xC05A,0x4488,0x4220,0x0003,0xC05A,0x4450,0x43E0,0x0003,
	X	0xC042,0x4450,0x4200,0x0003,0xC042,0x4420,0x4220,0x0003,
	X	0xC042,0x3820,0x41C0,0x0003,0xC000,0x0000,0x0000,0x0003,
	X	0xC000,0x0000,0x0001,0xC003,0xC000,0x0000,0x0001,0xC003,
	X	0xC000,0x0000,0x0001,0xC003,0xC000,0x0000,0x0000,0x1003,
	X	0xC000,0x0000,0x0000,0x8003,0xC000,0x0000,0x0000,0x0403,
	X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0083,
	X	0xC000,0x0000,0x0000,0x8003,0xC000,0x0000,0x0000,0x0003,
	X	0xC000,0x0000,0x0000,0x0073,0xC001,0x0000,0x0000,0x0E73,
	X	0xC002,0x0000,0x0000,0x8A73,0xC004,0x0000,0x0000,0x0A03,
	X	0xC00C,0x0000,0x0000,0x0E03,0xC012,0x0000,0x0000,0x0403,
	X	0xC023,0x0000,0x0000,0x8723,0xC047,0x8000,0x0000,0x0F03,
	X	0xC086,0x9B6D,0xB6D8,0x1A83,0xC047,0x8000,0x0000,0x0283,
	X	0xC023,0x0000,0x0000,0x0223,0xC012,0x0000,0x0000,0x8403,
	X	0xC00C,0x0000,0x0000,0x0603,0xC004,0x0000,0x0000,0x0E03,
	X	0xC002,0x0000,0x0000,0x1A23,0xC001,0x0000,0x0001,0xD203,
	X	0xC000,0x0000,0x0001,0xD103,0xC000,0x0000,0x0001,0xC123,
	X	0xC000,0x0000,0x0000,0x0103,0xC000,0x0000,0x0000,0x2003,
	X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0823,
	X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0203,
	X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x00A3,
	X	0xC000,0x0000,0x0000,0x0073,0xC000,0x0000,0x0000,0x0073,
	X	0xC000,0x0000,0x0000,0x0073,0xC000,0x0000,0x0000,0x0003,
	X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0003,
	X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0003,
	X	0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF
SHAR_EOF
if test 1933 -ne "`wc -c < 'movietool.icon'`"
then
	echo shar: error transmitting "'movietool.icon'" '(should have been 1933 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'movietool.man'" '(7082 characters)'
if test -f 'movietool.man'
then
	echo shar: will not over-write existing file "'movietool.man'"
else
sed 's/^	X//' << \SHAR_EOF > 'movietool.man'
	X.TH movietool L "30 May 1990"
	X.SH NAME
	XMovietool \- a display tool for sequences of
	X.I Sun rasterfiles
	Xproviding "video animation" in a Sun window.
	X.SH SYNOPSIS
	X.I movietool
	X.I [SunView Generic Args]
	X.I [-encoded]
	X.I [-zoom factor] 
	X.br
	X.I 	[-sub x y w h]
	X.I [-ident]
	X.I [-XOR]
	X.I [-background]
	X.br
	X.I 	rasterfile[s]
	X.SH DESCRIPTION
	X.I Movietool
	Xdisplays a sequence of color or monochrome raster files (see "man 5 rasterfile")
	Xin real-time or near-real-time.
	XOn a Sun 3/50M with 4 MB of RAM, monochrome images of 600 by 800 pixels
	Xmay be played at about 16 frames per second.
	X.I Movietool
	Xalso allows previewing single or multiple raster files,
	Xeven if you're not interested in animation.
	X.SH ARGUMENTS
	XAfter the SunView generic arguments (see generic_args(1)),
	XMovietool takes the following arguments:
	X.IP "-e[ncoded]"
	XWith this option,
	Xthe rasterfiles' data are stored as byte-encoded data
	X(provided the rasterfile format was
	X.I RT_BYTE_ENCODED).
	XThis could typically reduce memory consumption by as much as
	X.I 50-80 %,
	Xproviding much smoother animation, or longer sequences,
	Xwith a given amount of available RAM memory.
	XThe decoding process of course requires more of the CPU
	Xthan a simple memory copy operation,
	Xbut when you are lacking RAM memory this tradeoff is a big win.
	X.IP "-z[oom] factor"
	Xdoes raster replication to magnify your rasterfiles.
	XThe
	X.I factor
	Xmust be between 2 and 10,
	Xjust for safety.
	XThis option also works with the -encoded option,
	Xwhere rasters are zoomed during the decoding process.
	X.IP "-s[ub] x y w h"
	Xpicks a 
	X.I subregion
	Xof your rasterfiles starting at pixel (x,y) of width=w and height=h.
	XThis option has not been implemented for the -encoded option yet,
	Xso Movietool will refuse the -s together with the -e flag.
	X.IP "-i[dent]"
	XUse 
	X.I identical colormaps
	Xfor all (color) frames,
	Xthereby reducing memory and time consumption.
	XThe color map of the first frame is used throughout.
	X.IP "-X[OR]"
	XFor a sequence of rasterfiles, store the
	X.I XOR
	Xof successive rasters.
	XWhen playing a sequence, the updating takes place by means of XOR-ing
	Xwhat is on the screen.
	XSince most of the XOR'ed pixels are presumably zero,
	Xthis provides the possibility for very fast updating of the screen.
	XHowever, the simple frame buffers
	X(I have tried /dev/bwtwo1, /dev/cgfour0 and /dev/cgtwo0 with GP2)
	Xdo not appear to do XOR's efficiently.
	XThis option does not work with the -encoded option.
	X.IP "-b[ackground]"
	XThe canvas background will be painted the color of the upper left,
	Xor first, pixel of the first image,
	Xrather than the default SunView color.
	XThe background is the area of the canvas not covered by the
	Xraster image currently displayed.
	X.IP "-a[udio]"
	XPlay an audio file on the system's speaker.
	XThe audio filename can only be changed by recompiling Movietool.
	X.IP "rasterfile[s]"
	Xargument[s] must be in the
	X.I rasterfile(5)
	Xformat.
	XFiles not conforming to this format are just ignored.
	X.SH "CONTROL PANEL"
	XThere are
	X.I Play
	X(animate the sequence),
	X.I Step
	X(single step through the movie),
	X.I Clear
	X(clear display canvas), and
	X.I Eject
	X(finish up) buttons on the control panel.
	XIf only a single rasterfile is to be displayed,
	Xthe control panel consists of only the Eject button.
	X.LP
	XWhile the movie is playing,
	Xthe mouse cursor shows an hour-glass in the control panel,
	Xand the movie may only be interrupted by pressing the
	X.I STOP
	Xbutton located at the top left-hand corner of the keyboard
	X(\fIL1\fP on many keyboards).
	XSince the display-canvas is non-retained and attempts to use the overlay
	Xplane on the framebuffer (if available),
	Xdamage to the window is not repaired while the movie is playing.
	XTo repair, interrupt the movie and restart it.
	X.LP
	XIf the
	X.I -XOR
	Xoption has been selected,
	Xthe first line of the panel also features a switch between
	XXOR-ing and a normal copy,
	Xas well as the possibility to view the XOR'ed raster.
	X.LP
	XSecond line features a 
	X.I Frame
	Xslider indicating framenumber as the movie proceeds,
	Xwhich in addition may be used to position at a particular frame.
	XThe file name corresponding to the current frame is displayed
	X(except when Playing).
	X.LP
	XThird line shows,
	Xand allows selection of,
	Xplay 
	X.I Direction: forward
	Xor
	X.I backward.
	X.PP
	XFourth line controls repetition of the movie:
	XThe
	X.I Repeat
	Xbutton allows repetition as indicated by Direction.
	XIf
	X.I Auto-reverse
	Xis flipped on,
	Xthe movie turns around at either end.
	XIn this case, the Repeat button is disabled.
	X.PP
	XIf you toggle the
	X.I Clipping
	Xbutton "Off",
	Xan attempt will be made to decode
	Xthe rasterfiles directly onto the screen pixrect,
	Xwhen pressing the "Play" button.
	XThis is mostly useful when playing RT_BYTE_ENCODED raster images,
	Xwhere you avoid the internal copying to a memory pixrect
	Xbefore displaying on the screen.
	XIt is your own
	X.I responsibility
	Xto enlarge Movietool sufficiently so that the Clipping Off option does
	Xnot damage other windows !
	XIf you disable clipping,
	Xit is recommended to zoom up Movietool by using the Resize=>FullScreen popup.
	XHowever, even if you disable clipping,
	XMovietool may not always be able to provide faster display,
	Xand clipping may occur correctly anyway.
	XAlso, when single-stepping through rasterfiles,
	Xclipping will be performed because speed is not an issue.
	X.LP
	XFinally, the
	X.I Frames/sec
	Xslider lets you select the speed of the movie.
	XBy choosing the maximum value, you get whatever maximum performance
	Xyour system will deliver.
	XAt lower values delays will be imposed,
	Xbut if the actual speed is lower than the value selected,
	Xthe slider will flick to the current number of frames per second.
	XNote that the system's time-of-day clock is so coarse that at above 16
	Xframes/sec it is hard to provide proper timing.
	X.SH PICTURE DISPLAY
	XThe raster image will always be centered on the display canvas,
	Xprovided the canvas is large enough.
	XIn case your image is larger than the available canvas,
	Xthe scroll bars allow you to select part of the image.
	X.SH CAPACITY
	XOn a 3/60C, the rate at which rasters can be displayed on the screen
	Xseems to be about 6-8 Mega-pixels per second,
	Xwhich may easily be 25-50 frames per second for small images.
	XMonochrome images generally play 8 times faster than color images of
	Xthe same size.
	XAlso, if the Movietool is shrunk to display just the interesting region of
	Xthe rasterfiles (or when using the
	X.I -sub
	Xargument),
	Xthe display may become significantly faster.
	XThe most important limitation to long image sequences is the amount
	Xof RAM available to hold the memory-pixrects containing the images.
	XWhen paging to the disk sets in, 
	Xyou will notice immediately !
	X.SH AUTHOR
	XMovietool was written by:
	X.nf
	XOle H. Nielsen
	XLab of Applied Physics, Bygn. 307
	XTechnical University of Denmark, DK-2800 Lyngby, Denmark.
	XE-mail: ohnielse@ltf.dth.dk
	X.fi
	X.LP
	XYou may redistribute Movietool freely,
	Xprovided you maintain the Copyright notice of the author,
	Xand provided you don't attempt to sell Movietool for profit.
	X.LP
	XThe development of
	XMovietool was inspired by a similar tool called VCR by 
	XHsuan Chang (hsc@vuse.vanderbilt.edu),
	Xbut Movietool has rather improved functionality and performance.
SHAR_EOF
if test 7082 -ne "`wc -c < 'movietool.man'`"
then
	echo shar: error transmitting "'movietool.man'" '(should have been 7082 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(1196 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile'
	X# PROFILE_FLAG=-pg
	XCFLAGS = -O ${PROFILE_FLAG}
	X
	XLIBS = -lsuntool -lsunwindow -lpixrect
	X# For profiling:
	X# LIBS = -lsuntool_p -lsunwindow_p -lpixrect_p
	X
	X# Change the AUDIOPLAYER and AUDIODIR definitions,
	X# or comment out the next 2 lines if you don't have audio 
	XAUDIOPLAYER = /usr/local/bin/play
	XAUDIODIR = /usr/local/common/audio
	X
	X# Installation directories etc.
	XBINDIR = /usr/local/bin
	XMANEXT = l
	XMANDIR = /usr/man/man${MANEXT}
	X
	XOBJS = main.o frames.o zoom.o pr_load.o pr_decode.o pw_rop.o paneledit.o audio.o
	X
	Xmovietool: movietool.o movietool.h ${OBJS}
	X	cc ${CFLAGS} -o movietool movietool.o ${OBJS} ${LIBS}
	X
	Xplay: play.c
	X	cc ${CFLAGS} -o play play.c
	X
	Xpw_decode.o: pw_decode.c
	X	${CC} -O4 ${PROFILE_FLAG} -c pw_decode.c
	X
	Xpr_decode.o: pr_decode.c
	X	${CC} -O4 ${PROFILE_FLAG} -c pr_decode.c
	X
	Xpr_load.o: pr_load.c
	X	${CC} -O4 ${PROFILE_FLAG} -c pr_load.c
	X
	Xzoom.o: zoom.c
	X	${CC} -O4 ${PROFILE_FLAG} -c zoom.c
	X
	Xaudio.o: audio.c
	X	${CC} ${CFLAGS} -DAUDIOPLAYER=\"${AUDIOPLAYER}\" -DAUDIODIR=\"${AUDIODIR}\" -c audio.c
	X
	X${OBJS}: movietool.h
	X
	Xmovietool.o: movietool.icon
	X
	Xinstall: movietool
	X	install -s movietool ${BINDIR}
	X	cp movietool.man ${MANDIR}/movietool.${MANEXT}
	X
	Xclean:
	X	rm -f core *.o movietool
SHAR_EOF
if test 1196 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 1196 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'COPYRIGHT'" '(516 characters)'
if test -f 'COPYRIGHT'
then
	echo shar: will not over-write existing file "'COPYRIGHT'"
else
sed 's/^	X//' << \SHAR_EOF > 'COPYRIGHT'
	X/*
	X * This file is part of
	X * Movietool: display a succession of rasterfile frames in real-time
	X *
	X * Copyright 1989, 1990 by Ole H. Nielsen
	X * This software may be distributed freely provided that:
	X * 1) this copyright notice is kept intact,
	X * 2) you do not try to sell this software for a profit,
	X * 3) you provide the full source code.
	X *
	X * Author: Ole H. Nielsen
	X *         Lab of Applied Physics, Bygn. 307
	X *         Technical University of Denmark, DK-2800 Lyngby
	X *         E-mail: ohnielse@ltf.dth.dk
	X */
SHAR_EOF
if test 516 -ne "`wc -c < 'COPYRIGHT'`"
then
	echo shar: error transmitting "'COPYRIGHT'" '(should have been 516 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'VERSION'" '(30 characters)'
if test -f 'VERSION'
then
	echo shar: will not over-write existing file "'VERSION'"
else
sed 's/^	X//' << \SHAR_EOF > 'VERSION'
	XThis is movietool version 1.1
SHAR_EOF
if test 30 -ne "`wc -c < 'VERSION'`"
then
	echo shar: error transmitting "'VERSION'" '(should have been 30 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'play.c'" '(8639 characters)'
if test -f 'play.c'
then
	echo shar: will not over-write existing file "'play.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'play.c'
	X/*				Play.c					*/
	X/*	This program will play sound files in u-law format on the 	*/
	X/*	Sparcstation I.  It is a modification of Sun's sound.c program	*/
	X/*	distributed with SunOS.  These modifications were done by	*/
	X/*	Richard Gopstein (..!rutgers!soleil!gopstein), September 1989	*/
	X
	X#include <sys/types.h>
	X#include <sys/time.h>
	X#include <sys/dir.h>
	X#include <sys/file.h>
	X
	X#include <fcntl.h>
	X#include <errno.h>
	X#include <stdio.h>
	X
	X#include <sys/ioctl.h>
	X#include <sbusdev/audioreg.h>
	X#include <sun/audioio.h>
	X
	X#define WRITE_SIZE			4096
	X
	X#define BUFFER_SIZE	819200
	X
	X#define NOTIFIER_LOOP_DELAY	50000
	X
	Xint	Audio_fd;
	Xint	fd;
	Xint	Compress = 1;
	Xint     play_flag = 1;
	X
	X#define MODULATION_U_LAW	1
	X#define MODULATION_A_LAW	2
	X#define MODULATION_BINARY	3
	X
	Xstruct sound_buffer {
	X	int	bits_per_sample;
	X	int	samples_per_second;
	X	int	channels;
	X	int	modulation;
	X	int	allocated;
	X	int	size;
	X	int	cursor_1;
	X	int	cursor_2;
	X	int	cursor_start;
	X	int	cursor_end;
	X	int	display_position;
	X	int	last_displayed;
	X	int	io_position;
	X	char	directory[256];
	X	char	filename[256];
	X	char	data[BUFFER_SIZE];
	X} Buffer;
	X
	X
	Xmain(argc,argv)
	X	int	argc;
	X	char	**argv;
	X{
	X        int volume;
	X
	X	if ((argc != 2) && (argc != 4)) {
	X	  fprintf(stderr, "Usage: play [-v volume] soundfile\n");
	X		exit(1);
	X	}
	X
	X	argv++;
	X
	X	if (argc == 4) {
	X
	X	  if (strcmp(*argv++, "-v") != 0) {
	X	    fprintf(stderr, "Usage: play [-v volume] soundfile\n");
	X	    exit(1);
	X	  } else {
	X	    volume = atoi(*argv++) * 3;
	X	  }
	X
	X	} else {
	X
	X          volume = 21;
	X	}
	X
	X	buffer_initialize(&Buffer);
	X
	X        file_open(*argv);
	X
	X	audio_open();
	X
	X        main_play_volume_proc(volume);
	X
	X        while(play_flag) {
	X          main_play();
	X		nap(NOTIFIER_LOOP_DELAY);
	X	}
	X}
	X
	X/*  This is the routine that is called from the main loop that writes
	X *  sound to the device.
	X *
	X *  It needs the following state data:
	X	- cursor start and end (calculate in proc)
	X *	- current position in the buffer
	X */
	X
	Xmain_play_volume_proc(value)
	X	int	value;
	X{
	X	int	gr;
	X	int	ger;
	X
	X	ger = value/2;
	X	gr = value - ger;
	X	if (ger < -10) {
	X		ger = -10;
	X		gr = value - ger;
	X	}
	X	if (gr > 12) {
	X		gr = 12;
	X		ger = value - gr;
	X	}
	X
	X	if ((gr + ger) != value) {
	X		fprintf(stderr,
	X		"Error: gr (%d) + ger (%d) != value (%d)\n",
	X		    gr,ger,value);
	X	}
	X
	X	audio_set_gr(gr);
	X	audio_set_ger(ger);
	X}
	X
	Xmain_play()
	X
	X{
	X	int	bytes;
	X	int	start;
	X	int	end;
	X	int	queue_size;
	X	int	display_position;
	X	int	rtn;
	X
	X	/*  Calculate the cursor positions every time we enter this loop.
	X	 *  This will let us change the cursors on the fly and have them
	X	 *  take effect immediately.
	X	 */
	X	if (Buffer.cursor_1 < Buffer.cursor_2) {
	X		Buffer.cursor_start = Buffer.cursor_1;
	X		Buffer.cursor_end = Buffer.cursor_2;
	X	} else {
	X		Buffer.cursor_start = Buffer.cursor_2;
	X		Buffer.cursor_end = Buffer.cursor_1;
	X	}
	X
	X	/*  See if there is enough room in the device for another block
	X	 *  of sound.  We want to write in large chunks and keep as much
	X	 *  data enqueued as possible.
	X	 */
	X		if (ioctl(Audio_fd,AUDIOWRITEQ,&bytes) < 0) {
	X			perror("AUDIOWRITEQ ioctl failed");
	X		}
	X
	X		if (ioctl(Audio_fd,AUDIOGETQSIZE,&queue_size) < 0) {
	X			perror("AUDIOGETQSIZE ioctl failed");
	X		}
	X
	X	start = Buffer.io_position;
	X	end = start + WRITE_SIZE;
	X	if (((queue_size - bytes) > WRITE_SIZE) &&
	X	    (start < Buffer.cursor_end)) {
	X		if (end > Buffer.cursor_end) {
	X			end = Buffer.cursor_end;
	X		}
	X		Buffer.io_position = end;
	X
	X			rtn = write(Audio_fd,&Buffer.data[start],
	X			    end - start);
	X			if (rtn < 0) {
	X		  perror("audio write");
	X			}
	X		}
	X
	X		if (ioctl(Audio_fd,AUDIOWRITEQ,&bytes) < 0) {
	X			perror("AUDIOWRITEQ ioctl failed");
	X		}
	X
	X
	X	/*  XXX We don't want to return until we are done playing the sound.
	X	 */
	X
	X	if ((end >= Buffer.cursor_end) && (bytes == 0)) {
	X
	X
	X			main_play_off();
	X		}
	X	}
	X
	X
	X/*  This routine is used when we stop playing sound, for whatever reason.
	X */
	Xmain_play_off()
	X
	X{
	X	int	dummy;
	X
	X		if (ioctl(Audio_fd,AUDIOSTOP,&dummy) < 0) {
	X			perror("AUDIOSTOP ioctl failed");
	X		}
	X
	X        play_flag = 0;
	X
	X}
	X
	Xfile_open(path)
	Xchar *path;
	X{
	X
	X
	X	if ((fd = open(path,0)) < 0) {
	X		perror("Error opening input file");
	X		return;
	X	}
	X
	X	Buffer.size = read(fd,Buffer.data,BUFFER_SIZE);
	X	Buffer.display_position = 0;
	X	Buffer.samples_per_second = 8192;
	X	Buffer.bits_per_sample = 8;
	X	Buffer.channels = 1;
	X	Buffer.modulation = MODULATION_U_LAW;
	X	Buffer.cursor_1 = 0;
	X	Buffer.cursor_2 = Buffer.size - 1;
	X	Compress = 1;
	X
	X}
	X
	Xaudio_open()
	X{
	X	struct	audio_ioctl	tmp;
	X
	X	if ((Audio_fd = open("/dev/audio",2)) < 0) {
	X		perror("/dev/audio");
	X		exit(1);
	X	}
	X
	X	/* Initialize the three gain registers to 0db. */
	X	audio_set_ger(0);
	X	audio_set_gr(0);
	X	audio_set_gx(0);
	X
	X	/*
	X	 * Tell the chip to set the gains according to the
	X	 * register values we just set.
	X	 */
	X
	X	tmp.control = AUDIO_MAP_MMR1;
	X	tmp.data[0] = AUDIO_MMR1_BITS_LOAD_GX |
	X	    AUDIO_MMR1_BITS_LOAD_GR |
	X	    AUDIO_MMR1_BITS_LOAD_GER;
	X
	X		if (ioctl(Audio_fd,AUDIOSETREG,&tmp) < 0) {
	X			perror("Set REG");
	X		}
	X
	X	/*  Initialize the MMR2 register to send the output to the builtin
	X	 *  speaker.  This is the default, but we will be defensive
	X	 *  anyway.  Note that we read the register and turn on the
	X	 *  appropriate bit, rather thanjust setting it.  This keeps us
	X	 *  from stompin any useful bits that are already set.  It turns
	X	 *  out that there is one -- the bit that selects AINB for
	X	 *  recording.
	X	 */
	X		tmp.control = AUDIO_MAP_MMR2;
	X		if (ioctl(Audio_fd,AUDIOGETREG,&tmp) < 0) {
	X			perror("Set REG");
	X		}
	X
	X		tmp.data[0] |= AUDIO_MMR2_BITS_LS;
	X		if (ioctl(Audio_fd,AUDIOSETREG,&tmp) < 0) {
	X			perror("Set REG");
	X		}
	X	}
	X
	X
	X	/*	These are tables of values to be loaded into various
	X		gain registers.
	X
	X		Note that for the ger entry for -8db, we use the data
	X		sheet value for -7.5db.  The data sheet gives values for
	X		-8db which are wrong and produce too much gain.
	X	*/
	X
	Xstatic	unsigned char ger_table[][2] = {
	X		0xaa,	0xaa,	/* -10db */
	X		0x79,	0xac,
	X		/*0x41,	0x91,*/
	X		0x31,	0x99,	/* -7.5db */
	X		0x9c,	0xde,
	X		0x74,	0x9c,	/* -6db */
	X		0x6a,	0xae,
	X		0xab,	0xdf,
	X		0x64,	0xab,
	X		0x2a,	0xbd,
	X		0x5c,	0xce,
	X		0x00,	0x99,	/* 0db */
	X		0x43,	0xdd,
	X		0x52,	0xef,
	X		0x55,	0x42,
	X		0x31,	0xdd,
	X		0x43,	0x1f,
	X		0x40,	0xdd,	/* 6db */
	X		0x44,	0x0f,
	X		0x31,	0x1f,
	X		0x10,	0xdd,
	X		0x41,	0x0f,
	X		0x60,	0x0b,
	X		0x42,	0x10,	/* 12db */
	X		0x11,	0x0f,
	X		0x72,	0x00,
	X		0x21,	0x10,
	X		0x22,	0x00,
	X		0x00,	0x0b,
	X		0x00,	0x0f,	/* 18db */
	X};
	X
	X
	Xstatic	unsigned char gr_gx_table[][2] = {
	X		0x8b,	0x7c,	/* -18db */
	X		0x8b,	0x35,
	X		0x8b,	0x24,
	X		0x91,	0x23,
	X		0x91,	0x2a,
	X		0x91,	0x3b,
	X		0x91,	0xf9,	/* -12db */
	X		0x91,	0xb6,
	X		0x91,	0xa4,
	X		0x92,	0x32,
	X		0x92,	0xaa,
	X		0x93,	0xb3,
	X		0x9f,	0x91,	/* -6db */
	X		0x9b,	0xf9,
	X		0x9a,	0x4a,
	X		0xa2,	0xa2,
	X		0xaa,	0xa3,
	X		0xbb,	0x52,
	X		0x08,	0x08,	/* 0db */
	X		0x3d,	0xac,
	X		0x25,	0x33,
	X		0x21,	0x22,
	X		0x12,	0xa2,
	X		0x11,	0x3b,
	X		0x10,	0xf2,	/* 6db */
	X		0x02,	0xca,
	X		0x01,	0x5a,
	X		0x01,	0x12,
	X		0x00,	0x32,
	X		0x00,	0x13,
	X		0x00,	0x0e,	/* 12db */
	X};
	X
	X
	X
	Xaudio_set_ger(value)
	X	int	value;
	X{
	X	struct	audio_ioctl	tmp;
	X
	X
	X	if ((value < -10) || (value > 18)) {
	X		fprintf(stderr,
	X		    "GER value %d out of range; %d <= GER <=  %d\n",
	X		    value,0,18);
	X		return;
	X	}
	X
	X	/*  Add 10 to the value to get the index into the table.
	X	 */
	X	tmp.control = AUDIO_MAP_GER;
	X	tmp.data[0] = ger_table[value + 10][1];
	X	tmp.data[1] = ger_table[value + 10][0];
	X
	X		if (ioctl(Audio_fd,AUDIOSETREG,&tmp) < 0) {
	X			perror("Set REG");
	X		}
	X	}
	X
	X
	Xaudio_set_gr(value)
	X	int	value;
	X{
	X	struct	audio_ioctl	tmp;
	X
	X	if ((value < -18) || (value > 12)) {
	X		fprintf(stderr,
	X		    "GR value %d out of range; %d <= GR <=  %d\n",
	X		    value,0,12);
	X		return;
	X	}
	X
	X	tmp.control = AUDIO_MAP_GR;
	X	tmp.data[0] = gr_gx_table[value + 18][1];
	X	tmp.data[1] = gr_gx_table[value + 18][0];
	X
	X
	X		if (ioctl(Audio_fd,AUDIOSETREG,&tmp) < 0) {
	X			perror("Set REG");
	X		}
	X
	X	}
	X
	X
	Xaudio_set_gx(value)
	X	int	value;
	X{
	X	struct	audio_ioctl	tmp;
	X
	X	if ((value < -18) || (value > 12)) {
	X		fprintf(stderr, 
	X		    "GX value %d out of range; %d <= GX <=  %d\n",
	X		    value,0,12);
	X		return;
	X	}
	X
	X	/*  We add 18 to get the index into the table, since entry 0 represents
	X	 *  -18db.
	X	 */
	X	tmp.control = AUDIO_MAP_GX;
	X	tmp.data[0] = gr_gx_table[value + 18][1];
	X	tmp.data[1] = gr_gx_table[value + 18][0];
	X
	X		if (ioctl(Audio_fd,AUDIOSETREG,&tmp) < 0) {
	X			perror("Set REG");
	X		}
	X	}
	X
	Xbuffer_initialize(buffer)
	X	struct	sound_buffer	*buffer;
	X{
	X	extern char *getwd();
	X
	X	buffer->size = 0;
	X	buffer->filename[0] = 0;
	X	buffer->cursor_1 = 0;
	X	buffer->cursor_2 = 0;
	X
	X	bzero(buffer->data, buffer->size);
	X
	X	if (!getwd(Buffer.directory))
	X		strcpy(Buffer.directory, ".");
	X}
	X
	X
	Xstatic
	Xnap(usec)
	X	int usec;
	X{
	X	struct timeval timeout;
	X
	X	timeout.tv_sec = 0;
	X	timeout.tv_usec = usec;
	X
	X	(void) select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0,
	X		&timeout);
	X}
	X
	X
SHAR_EOF
if test 8639 -ne "`wc -c < 'play.c'`"
then
	echo shar: error transmitting "'play.c'" '(should have been 8639 characters)'
fi
fi # end of overwriting check
echo shar: done with directory "'movietool-1.1'"
cd ..
#	End of shell archive
exit 0
