[comp.sources.sun] v01i083: Trackertool-Graph data coming from a pipe

mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) (11/29/89)

Submitted-by: rphroy!rrichter@edsews.eds.com (Roy Richter)
Posting-number: Volume 1, Issue 83
Archive-name: trackertool/part02




#--------------------------------CUT HERE-------------------------------------
#! /bin/sh
#
# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-r--r--  1 roy          1623 Oct 13 16:29 make_base.c
# -rw-r--r--  1 roy          2230 Oct 12 10:00 make_labels.c
# -rw-r--r--  1 roy          3544 Oct 12 10:01 make_panel.c
# -rw-r--r--  1 roy          3562 Sep 14 16:28 make_props.c
# -rw-r--r--  1 roy          4800 Nov 29 09:58 make_sub.c
# -rw-r--r--  1 roy          3607 Oct 12 11:42 pipe_reader.c
# -rw-r--r--  1 roy          1283 Oct 12 10:58 quit_proc.c
# -rw-r--r--  1 roy          8657 Oct 12 10:32 repaint_canvas.c
# -rw-r--r--  1 roy          1846 Sep 14 16:28 reset_axis_proc.c
# -rw-r--r--  1 roy          1535 Nov  9 11:45 rewrite_text.c
# -rw-r--r--  1 roy          2859 Nov 29 10:04 trackertool.c
# -rw-r--r--  1 roy          2057 Sep 14 16:28 update_arrays.c
# -rw-r--r--  1 roy          2275 Sep 14 16:28 update_canvas.c
# -rw-r--r--  1 roy          1658 Sep 14 16:28 update_displays.c
# -rw-r--r--  1 roy           657 Nov  9 11:37 update_textsw.c
# -rw-r--r--  1 roy          6211 Nov 29 10:06 zoom_event.c
#
echo 'x - make_base.c'
if test -f make_base.c
then echo 'shar: not overwriting make_base.c'; else
sed 's/^X//' << '________This_Is_The_END________' > make_base.c
X#include "trackertool.h"
X
Xstatic short    icon_image[] = {
X#include "trackertool.icon"
X};
XDEFINE_ICON_FROM_IMAGE(trackertool_icon, icon_image);
X
XFrame
Xmake_base(argc, argv)
X    int             argc;
X    char          **argv;
X{
X    Frame           base_frame;
X
X    void            make_sub();
X    void            quit_proc();
X    Notify_value    close_them_proc();
X
X    base_frame = window_create(NULL, FRAME,
X	FRAME_LABEL, "Trackertool               Copyright 1988, GM Corp.",
X	FRAME_ICON, &trackertool_icon,
X	WIN_ERROR_MSG, "Can't create window",
X	FRAME_ARGS, argc, argv,
X	0);
X
X    main_panel = window_create(base_frame, PANEL, 0);
X
X    view_button = panel_create_item(main_panel, PANEL_BUTTON,
X	PANEL_LABEL_IMAGE, panel_button_image(main_panel, "Create View", 0, 0),
X	PANEL_NOTIFY_PROC, make_sub,
X	0);
X
X    hide_button = panel_create_item(main_panel, PANEL_BUTTON,
X	PANEL_LABEL_IMAGE, panel_button_image(main_panel, "Hide", 0, 0),
X	PANEL_NOTIFY_PROC, quit_proc,
X	0);
X
X    quit_button = panel_create_item(main_panel, PANEL_BUTTON,
X	PANEL_LABEL_IMAGE, panel_button_image(main_panel, "Quit", 0, 0),
X	PANEL_NOTIFY_PROC, quit_proc,
X	0);
X
X    num_message = panel_create_item(main_panel, PANEL_MESSAGE,
X	PANEL_LABEL_STRING, "Reading..... Values:    0",
X	0);
X
X    window_fit(main_panel);
X    window_fit(base_frame);
X
X    num_of_subframes = -1;	/* subframe[0] not yet created */
X
X    /*
X     * File descriptor usage: 1  frame 1  panel
X     */
X    num_fd = num_fd + 2;
X
X    /* make sure I get when the base_frame opens/closes */
X    notify_interpose_event_func(base_frame, close_them_proc,
X	NOTIFY_SAFE);
X
X    return base_frame;
X}
________This_Is_The_END________
if test `wc -l < make_base.c` -ne 62; then
	echo -n 'shar: make_base.c was damaged during transit'
	echo ' (should have been 62 bytes)'
fi
fi		; : end of overwriting check
echo 'x - make_labels.c'
if test -f make_labels.c
then echo 'shar: not overwriting make_labels.c'; else
sed 's/^X//' << '________This_Is_The_END________' > make_labels.c
X#include <stdio.h>
X#include <string.h>
X#include "trackertool.h"
X
Xvoid
Xmake_labels()
X{
X    /*
X     * make_labels will read in the first line of stdin and setup the
X     * variable arrays to accept subsequent data. The first array is
X     * dummy, the record number. Both left and right-justified arrays
X     * are kept.
X     */
X
X    char            s_r[MAX_STR_LEN], s_l[MAX_STR_LEN];
X    int             get_next_string();
X
X    num_arrays = -1;
X    num_values = -1;
X
X    while (get_next_string(s_l, s_r, MAX_STR_LEN, stdin) != 0) {
X	if (num_arrays == MAX_ARRAYS - 2) {
X	    fprintf(stderr, "Maximum number of arrays reached.\n");
X	    return;
X	}
X	array_ptr[++num_arrays] = ALLOC(Array);
X	if (!array_ptr[num_arrays]) {
X	    fprintf(stderr, "Out of memory allocating array %d.\n", num_arrays);
X	    num_arrays -= 2;
X	    break;
X	}
X	array_ptr[num_arrays]->values =
X		(float *) malloc((unsigned) (MAX_VALUES * sizeof(float)));
X	array_ptr[num_arrays]->log_values =
X		(float *) malloc((unsigned) (MAX_VALUES * sizeof(float)));
X	if (!array_ptr[num_arrays]->values ||
X		!array_ptr[num_arrays]->log_values) {
X	    fprintf(stderr, "Out of memory allocating array %d.\n", num_arrays);
X	    num_arrays -= 2;
X	    break;
X	}
X	strcpy(array_ptr[num_arrays]->label_l, s_l);
X	strcpy(array_ptr[num_arrays]->label_r, s_r);
X	if (echo_on)
X	    printf("%s ", s_l);
X    }
X    if (echo_on)
X	printf("\n", s_l);
X
X    if (num_arrays < 0) {
X	fprintf(stderr, "Trackertool: no arrays input.  Stopping.\n");
X	exit(3);
X    }
X    /* allocate record # array if not already done */
X    if (!array_ptr[++num_arrays]) {
X	array_ptr[num_arrays] = ALLOC(Array);
X	array_ptr[num_arrays]->values =
X		(float *) malloc((unsigned) (MAX_VALUES * sizeof(float)));
X	array_ptr[num_arrays]->log_values =
X		(float *) malloc((unsigned) (MAX_VALUES * sizeof(float)));
X	if (!array_ptr[num_arrays]->values ||
X		!array_ptr[num_arrays]->log_values) {
X	    fprintf(stderr, "Out of memory allocating for Record Number.\n");
X	    fprintf(stderr, "%d arrays read in", --num_arrays);
X	    fprintf(stderr, " with %d values in each array.\n", MAX_VALUES);
X	}
X    }
X    strcpy(array_ptr[num_arrays]->label_l, "Record_#  ");
X    strcpy(array_ptr[num_arrays]->label_r, "  Record_#");
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < make_labels.c` -ne 72; then
	echo -n 'shar: make_labels.c was damaged during transit'
	echo ' (should have been 72 bytes)'
fi
fi		; : end of overwriting check
echo 'x - make_panel.c'
if test -f make_panel.c
then echo 'shar: not overwriting make_panel.c'; else
sed 's/^X//' << '________This_Is_The_END________' > make_panel.c
X#include <stdio.h>
X#include "trackertool.h"
X#define TEXT 0			/* the toggle values as set in make_sub */
X#define GRAPH 1
X#define PROPS 2
X#define PAN_L 3
X#define toggle_bit_on(value,bit) ((value) & (1 << (bit)))
X#define set_bit_on(value,bit) ((value) |= (1 << (bit)))
X
Xvoid
Xmake_panel(menu, menu_item)
X    Menu            menu;
X    Menu_item       menu_item;
X /*
X  * Re-shows the main panel after it's been deleted.
X  */
X{
X    Subframe       *subframe_ptr;
X    Panel           panel;
X    Attr_avlist     choice_list[MAX_ARRAYS + 2];
X    Rect           *rect;
X    unsigned int    value;
X    Event          *event;
X    int             i;
X
X    void            init_choices();
X    void            display_mode_proc();
X    void            change_variables_proc();
X    void            kill_view_proc();
X
X    /* See if we have a free fd to create panel. */
X    if (++num_fd > MAX_FD) {
X	fprintf(stderr, "Too many windows open.  Request ignored.\n");
X	num_fd--;
X	return;
X    }
X    /* Find which subframe we are in */
X    subframe_ptr = NULL;
X    for (i = 0; i <= num_of_subframes; i++) {
X	if (menu_item == subframe[i]->menu_item)
X	    subframe_ptr = subframe[i];
X    }
X    if (subframe_ptr == NULL) {
X	printf(stderr, "Internal error: can't find subframe.\n");
X	return;
X    }
X    /* Turn on the frame namestripe and turn off the menu item */
X    window_set(subframe_ptr->handle, FRAME_SHOW_LABEL, TRUE, 0);
X    menu_set(subframe_ptr->menu_item, MENU_INACTIVE, TRUE, 0);
X
X    /* Keep the current state of the world in value, for later use */
X    value = 0;
X    if (subframe_ptr->textsw)
X	set_bit_on(value, TEXT);
X    if (subframe_ptr->canvas)
X	set_bit_on(value, GRAPH);
X    if (subframe_ptr->props)
X	set_bit_on(value, PROPS);
X    set_bit_on(value, PAN_L);	/* since we want it on */
X
X    /*
X     * Make the panel again, from scratch; only use the data
X     * preferences already stored to set initial values for items
X     */
X    panel = window_create(subframe_ptr->handle, PANEL,
X	WIN_CLIENT_DATA, subframe_ptr,
X	WIN_X, 0,
X	WIN_Y, 0,
X	WIN_WIDTH, (int) window_get(subframe_ptr->handle, WIN_WIDTH, 0),
X	0);
X    subframe_ptr->panel = panel;
X
X    subframe_ptr->choice = panel_create_item(panel, PANEL_TOGGLE,
X	PANEL_LABEL_STRING, "Display mode:",
X	PANEL_CHOICE_STRINGS, "Text", "Graph", "Props", "This Panel", 0,
X	PANEL_TOGGLE_VALUE, TEXT, toggle_bit_on(value, TEXT),
X	PANEL_TOGGLE_VALUE, GRAPH, toggle_bit_on(value, GRAPH),
X	PANEL_TOGGLE_VALUE, PROPS, toggle_bit_on(value, PROPS),
X	PANEL_TOGGLE_VALUE, PAN_L, toggle_bit_on(value, PAN_L),
X	PANEL_NOTIFY_PROC, display_mode_proc,
X	0);
X    rect = (Rect *) panel_get(subframe_ptr->choice, PANEL_ITEM_RECT, 0);
X    init_choices(choice_list);
X    panel_create_item(panel, PANEL_CYCLE,
X	PANEL_LABEL_STRING, "Abcissa:",
X	ATTR_LIST, choice_list,
X	PANEL_NOTIFY_PROC, change_variables_proc,
X	PANEL_ITEM_X, 10,
X	PANEL_ITEM_Y, rect->r_height + 10,
X	PANEL_CLIENT_DATA, 'x',
X	PANEL_VALUE, 0,
X	0);
X    panel_create_item(panel, PANEL_CYCLE,
X	PANEL_LABEL_STRING, "Ordinate:",
X	ATTR_LIST, choice_list,
X	PANEL_NOTIFY_PROC, change_variables_proc,
X	PANEL_CLIENT_DATA, 'y',
X	PANEL_VALUE,
X	(num_of_subframes + 1 < num_arrays) ? num_of_subframes + 1 : 1,
X	0);
X    panel_create_item(panel, PANEL_BUTTON,
X	PANEL_LABEL_IMAGE, panel_button_image(panel, "Kill View", 0, 0),
X	PANEL_NOTIFY_PROC, kill_view_proc,
X	0);
X    window_fit_height(panel);
X
X    /*
X     * now we have our control panel back again. call display_mode_proc
X     * to make the other panels.
X     */
X    display_mode_proc(subframe_ptr->choice, value, event);
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < make_panel.c` -ne 114; then
	echo -n 'shar: make_panel.c was damaged during transit'
	echo ' (should have been 114 bytes)'
fi
fi		; : end of overwriting check
echo 'x - make_props.c'
if test -f make_props.c
then echo 'shar: not overwriting make_props.c'; else
sed 's/^X//' << '________This_Is_The_END________' > make_props.c
X#include <string.h>
X#include "trackertool.h"
X
XPanel
Xmake_props(subframe_ptr, frame, above_panel)
X    Subframe       *subframe_ptr;
X    Frame           frame;
X    Panel           above_panel;
X/*
X * Creates the props panel
X */
X{
X    Panel           props;
X
X    Panel_item      item;
X    Rect           *item_rect;
X
X    void            change_axis_proc();
X    void            reset_axis_proc();
X    void            change_connect_proc();
X
X    char            text_value[18];
X    char           *gcvt();
X
X    if (above_panel != NULL)
X	props = window_create(frame, PANEL,
X	    WIN_BELOW, above_panel,
X	    WIN_X, 0,
X	    WIN_CLIENT_DATA, subframe_ptr,
X	    0);
X    else
X	props = window_create(frame, PANEL,
X	    WIN_X, 0,
X	    WIN_Y, 0,
X	    WIN_CLIENT_DATA, subframe_ptr,
X	    0);
X    panel_create_item(props, PANEL_CYCLE,
X	PANEL_LABEL_STRING, "Draw Mode:",
X	PANEL_CHOICE_STRINGS, "Points", "Lines", 0,
X	PANEL_VALUE, subframe_ptr->connect_points,
X	PANEL_NOTIFY_PROC, change_connect_proc,
X	0);
X
X    window_fit_width(props);
X
X    item = panel_create_item(props, PANEL_TOGGLE,
X	PANEL_LAYOUT, PANEL_VERTICAL,
X	PANEL_LABEL_STRING, "X",
X	PANEL_CHOICE_STRINGS, "Auto min", "Auto Max",
X	"Grid", "Log", 0,
X	PANEL_TOGGLE_VALUE, 0, subframe_ptr->x_min_auto,
X	PANEL_TOGGLE_VALUE, 1, subframe_ptr->x_max_auto,
X	PANEL_TOGGLE_VALUE, 2, subframe_ptr->x_grid,
X	PANEL_TOGGLE_VALUE, 3, subframe_ptr->x_log,
X	PANEL_NOTIFY_PROC, change_axis_proc,
X	PANEL_SHOW_MENU, FALSE,
X	PANEL_CLIENT_DATA, 'x',
X	0);
X    item_rect = (Rect *) panel_get(item, PANEL_ITEM_RECT, 0);
X    panel_create_item(props, PANEL_TOGGLE,
X	PANEL_LAYOUT, PANEL_VERTICAL,
X	PANEL_LABEL_STRING, "Y",
X	PANEL_CHOICE_STRINGS, " ", " ", " ", " ", 0,
X	PANEL_TOGGLE_VALUE, 0, subframe_ptr->y_min_auto,
X	PANEL_TOGGLE_VALUE, 1, subframe_ptr->y_max_auto,
X	PANEL_TOGGLE_VALUE, 2, subframe_ptr->y_grid,
X	PANEL_TOGGLE_VALUE, 3, subframe_ptr->y_log,
X	PANEL_NOTIFY_PROC, change_axis_proc,
X	PANEL_SHOW_MENU, FALSE,
X	PANEL_CLIENT_DATA, 'y',
X	PANEL_ITEM_X, item_rect->r_left + item_rect->r_width + 10,
X	0);
X
X    panel_create_item(props, PANEL_BUTTON,
X	PANEL_LABEL_IMAGE, panel_button_image(props, "Reset", 0, 0),
X	PANEL_NOTIFY_PROC, reset_axis_proc,
X	PANEL_CLIENT_DATA, 1,
X	0);
X    panel_create_item(props, PANEL_BUTTON,
X	PANEL_LABEL_IMAGE, panel_button_image(props, "Redraw", 0, 0),
X	PANEL_NOTIFY_PROC, reset_axis_proc,
X	PANEL_CLIENT_DATA, 0,
X	0);
X
X    if (subframe_ptr->x_min_auto)
X	strcpy(text_value, "Not set");
X    else
X	gcvt(subframe_ptr->x_min, 8, text_value);
X    subframe_ptr->props_x_min = panel_create_item(props, PANEL_TEXT,
X	PANEL_LABEL_STRING, "X min:",
X	PANEL_VALUE_DISPLAY_LENGTH, MAX_STR_LEN,
X	PANEL_VALUE, text_value,
X	0);
X
X    if (subframe_ptr->x_max_auto)
X	strcpy(text_value, "Not set");
X    else
X	gcvt(subframe_ptr->x_max, 8, text_value);
X    subframe_ptr->props_x_max = panel_create_item(props, PANEL_TEXT,
X	PANEL_LABEL_STRING, "X max:",
X	PANEL_VALUE_DISPLAY_LENGTH, MAX_STR_LEN,
X	PANEL_VALUE, text_value,
X	0);
X
X    if (subframe_ptr->y_min_auto)
X	strcpy(text_value, "Not set");
X    else
X	gcvt(subframe_ptr->y_min, 8, text_value);
X    subframe_ptr->props_y_min = panel_create_item(props, PANEL_TEXT,
X	PANEL_LABEL_STRING, "Y min:",
X	PANEL_VALUE_DISPLAY_LENGTH, MAX_STR_LEN,
X	PANEL_VALUE, text_value,
X	0);
X
X    if (subframe_ptr->y_max_auto)
X	strcpy(text_value, "Not set");
X    else
X	gcvt(subframe_ptr->y_max, 8, text_value);
X    subframe_ptr->props_y_max = panel_create_item(props, PANEL_TEXT,
X	PANEL_LABEL_STRING, "Y max:",
X	PANEL_VALUE_DISPLAY_LENGTH, MAX_STR_LEN,
X	PANEL_VALUE, text_value,
X	0);
X
X    return (props);
X}
________This_Is_The_END________
if test `wc -l < make_props.c` -ne 126; then
	echo -n 'shar: make_props.c was damaged during transit'
	echo ' (should have been 126 bytes)'
fi
fi		; : end of overwriting check
echo 'x - make_sub.c'
if test -f make_sub.c
then echo 'shar: not overwriting make_sub.c'; else
sed 's/^X//' << '________This_Is_The_END________' > make_sub.c
X#include <stdio.h>
X#include "trackertool.h"
X
Xvoid
Xmake_sub(button)
X    Panel_item      button;
X{
X    Frame           frame, base_frame;
X    Panel           panel;
X    Subframe       *subframe_ptr;
X    Menu            menu;
X    Menu_item       menu_item;
X
X    void            repaint_canvas();
X    void            display_mode_proc();
X    void            change_variables_proc();
X    void            kill_view_proc();
X    void            init_arrays();
X    void            init_choices();
X    void            make_panel();
X    Notify_value    zoom_event();
X
X    char            string[22];
X    Attr_avlist     choice_list[MAX_ARRAYS + 2];
X    Rect           *rect;
X
X    /* gross hack from Chuck Musciano to remove subframe icon space */
X    char           *pos_hack[5];
X    static char     pos_hack_0[] = {""}, pos_hack_1[] = {"-WP"};
X    char            pos_hack_2[6] ,pos_hack_3[6];
X    static char     pos_hack_4[] = {""};
X    Rect           *fr;
X    pos_hack[0]=pos_hack_0;
X    pos_hack[1]=pos_hack_1;
X    pos_hack[2]=pos_hack_2;
X    pos_hack[3]=pos_hack_3;
X    pos_hack[4]=pos_hack_4;
X
X    /*
X     * check file descriptors.  We'll be making: 1 frame 1 panel 1
X     * canvas
X     */
X    if (num_fd + 3 > MAX_FD) {
X	fprintf(stderr, "Too many windows open.  Create ignored.\n");
X	panel_set(view_button, PANEL_SHOW_ITEM, FALSE, 0);
X	return;
X    } else
X	num_fd = num_fd + 3;
X
X    /* find the base frame of the button and its icon position */
X    base_frame = (Frame) window_get(
X	(Panel) panel_get(button, PANEL_PARENT_PANEL), WIN_OWNER);
X    fr = (Rect *) window_get(base_frame, FRAME_CLOSED_RECT);
X    sprintf(pos_hack[2], "%d", fr->r_left);
X    sprintf(pos_hack[3], "%d", fr->r_top);
X
X    /* create the new frame as a sub-frame of the base_frame.  */
X    sprintf(string, "Trackertool view #%2d", ++num_of_subframes + 1);
X    frame = window_create(base_frame, FRAME,
X	FRAME_ARGS, 4, pos_hack,
X	FRAME_LABEL, string,
X	WIN_CLIENT_DATA, num_of_subframes,
X	FRAME_SHOW_LABEL, TRUE,
X	WIN_ERROR_MSG, "Can't create subframe",
X	0);
X
X    /* get memory for subframe register and register it */
X    subframe[num_of_subframes] = ALLOC(Subframe);
X    subframe_ptr = subframe[num_of_subframes];
X    subframe_ptr->handle = frame;
X
X    /* set the default variables */
X    init_arrays(subframe_ptr);
X
X    /* set the current label list */
X    init_choices(choice_list);
X
X    /* Create the various parts of the subframe */
X    panel = window_create(frame, PANEL,
X	WIN_CLIENT_DATA, subframe_ptr,
X	0);
X    subframe_ptr->panel = panel;
X
X    subframe_ptr->choice = panel_create_item(panel, PANEL_TOGGLE,
X	PANEL_LABEL_STRING, "Display mode:",
X	PANEL_CHOICE_STRINGS, "Text", "Graph", "Props", "This Panel", 0,
X	PANEL_TOGGLE_VALUE, 1, TRUE,
X	PANEL_TOGGLE_VALUE, 3, TRUE,
X	PANEL_NOTIFY_PROC, display_mode_proc,
X	0);
X    rect = (Rect *) panel_get(subframe_ptr->choice, PANEL_ITEM_RECT, 0);
X    panel_create_item(panel, PANEL_CYCLE,
X	PANEL_LABEL_STRING, "Abcissa:",
X	ATTR_LIST, choice_list,
X	PANEL_NOTIFY_PROC, change_variables_proc,
X	PANEL_ITEM_X, 10,
X	PANEL_ITEM_Y, rect->r_height + 10,
X	PANEL_CLIENT_DATA, 'x',
X	PANEL_VALUE, 0,
X	0);
X    panel_create_item(panel, PANEL_CYCLE,
X	PANEL_LABEL_STRING, "Ordinate:",
X	ATTR_LIST, choice_list,
X	PANEL_NOTIFY_PROC, change_variables_proc,
X	PANEL_CLIENT_DATA, 'y',
X	PANEL_VALUE,
X	(num_of_subframes + 1 < num_arrays) ? num_of_subframes + 1 : 1,
X	0);
X    panel_create_item(panel, PANEL_BUTTON,
X	PANEL_LABEL_IMAGE, panel_button_image(panel, "Kill View", 0, 0),
X	PANEL_NOTIFY_PROC, kill_view_proc,
X	0);
X    window_fit(panel);
X    window_fit_width(frame);
X
X    subframe_ptr->textsw = 0;
X    subframe_ptr->props = 0;
X
X    subframe_ptr->canvas = window_create(frame, CANVAS,
X	CANVAS_REPAINT_PROC, repaint_canvas,
X	CANVAS_FIXED_IMAGE, FALSE,
X	CANVAS_RETAINED, FALSE,
X	WIN_BELOW, panel,
X	WIN_WIDTH, (int) window_get(frame, WIN_WIDTH, 0),
X	WIN_HEIGHT, (int) window_get(frame, WIN_WIDTH, 0),
X	WIN_EVENT_PROC, zoom_event,
X	WIN_CLIENT_DATA, subframe_ptr,
X	0);
X    repaint_canvas(subframe_ptr->canvas);
X
X    window_fit(frame);
X
X    /* Add menu item to base frame to re-create base panel */
X    menu = window_get(frame, WIN_MENU);
X    menu_item = menu_create_item(MENU_STRING, "Re-create panel",
X	MENU_INACTIVE, TRUE,
X	MENU_ACTION_PROC, make_panel,
X	0);
X    subframe_ptr->menu_item = menu_item;
X    menu_set(menu, MENU_APPEND_ITEM, menu_item, 0);
X    menu_set(menu_item, MENU_INACTIVE, TRUE, 0);	/* Don't show it yet */
X
X    /* Turn it on. */
X    window_set(subframe_ptr->canvas, WIN_SHOW, TRUE, 0);
X    window_set(frame, WIN_SHOW, TRUE, 0);
X
X    /* Check to see if we are at the limit of subframes */
X    if (num_of_subframes == MAX_SUBFRAMES - 1) {
X	panel_set(view_button, PANEL_SHOW_ITEM, FALSE, 0);
X    }
X    if (num_fd + 3 > MAX_FD)
X	panel_set(view_button, PANEL_SHOW_ITEM, FALSE, 0);
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < make_sub.c` -ne 155; then
	echo -n 'shar: make_sub.c was damaged during transit'
	echo ' (should have been 155 bytes)'
fi
fi		; : end of overwriting check
echo 'x - pipe_reader.c'
if test -f pipe_reader.c
then echo 'shar: not overwriting pipe_reader.c'; else
sed 's/^X//' << '________This_Is_The_END________' > pipe_reader.c
X#include <stdio.h>
X#include <math.h>
X#include "trackertool.h"
X
XNotify_value
Xpipe_reader(unique_handle, fd)
X    int            *unique_handle;
X    int             fd;
X{
X    /*
X     * pipe_reader is called when there is input pending. It reads in
X     * the data.  It also fakes an array value for the line number in
X     * Array[num_arrays].
X     */
X    int             offset;
X    int             i, j;
X    int             EOF_there;
X    static char     string[26] = {"End of data: Values:    0"};
X
X    void            get_axis_bounds(), get_axis_log_bounds();
X    void            update_arrays(), update_displays();
X    void            rewrite_text();
X    float           newmin, newmax, newmin_log;
X
X    /* Check to see if we have too many values */
X    if (++num_values == MAX_VALUES) {
X	offset = MAX_VALUES / 2;
X	for (i = 0; i <= num_arrays; i++) {
X	    newmin = array_ptr[i]->values[0 + offset];
X	    newmax = array_ptr[i]->values[0 + offset];
X	    if (array_ptr[i]->values[0 + offset] > 0.)
X		newmin_log = array_ptr[i]->values[0 + offset];
X	    else
X		newmin_log = 0.;
X	    for (j = 0; j < offset; j++) {
X		array_ptr[i]->values[j] = array_ptr[i]->values[j + offset];
X		array_ptr[i]->log_values[j] =
X			array_ptr[i]->log_values[j + offset];
X		if (array_ptr[i]->values[j] < newmin)
X		    newmin = array_ptr[i]->values[j];
X		if (array_ptr[i]->values[j] > newmax)
X		    newmax = array_ptr[i]->values[j];
X		if ((array_ptr[i]->values[j] < newmin_log || newmin_log == 0.)
X		    && array_ptr[i]->values[j] > 0.)
X		    newmin_log = array_ptr[i]->values[j];
X	    }
X	    array_ptr[i]->min_value = newmin;
X	    array_ptr[i]->max_value = newmax;
X	    get_axis_bounds(array_ptr[i]->min_value, array_ptr[i]->max_value,
X		&(array_ptr[i]->min_graph), &(array_ptr[i]->max_graph));
X	    array_ptr[i]->min_value_log = newmin_log;
X	    get_axis_log_bounds(
X		  array_ptr[i]->min_value_log,    array_ptr[i]->max_value,
X		&(array_ptr[i]->min_graph_log), &(array_ptr[i]->max_graph_log));
X	}
X	num_values = j;
X
X	/*
X	 * Also, the textsw's can only hold so much.  Check to see if
X	 * they are holding more than 4 sets of values.  If so, reset
X	 * them to only hold the last.  This 4 is set in
X	 * TEXTSW_MEMORY_MAXIMUM, in display_mode_proc().
X	 */
X	for (i = 0; i <= num_of_subframes; i++) {
X	    if (subframe[i]->textsw)
X		if ((int) window_get(subframe[i]->textsw, TEXTSW_LENGTH, 0)
X			> 21 * MAX_VALUES * 4)
X		    rewrite_text(subframe[i]->textsw);
X	}
X    }
X    /* Read in subsequent arrays from input */
X    for (i = 0; i < num_arrays; i++) {
X	EOF_there = scanf("%f", &(array_ptr[i]->values[num_values]));
X	if (EOF_there != EOF) {
X	    if (echo_on)
X		printf("%f ", array_ptr[i]->values[num_values]);
X	    if (array_ptr[i]->values[num_values] > 0)
X		array_ptr[i]->log_values[num_values] =
X			log10((double) array_ptr[i]->values[num_values]);
X	    else
X		array_ptr[i]->log_values[num_values] = 0.;
X	}
X    }
X    scanf("%*[^\n]");		/* skip over extra data until newline */
X    if (echo_on)
X	printf("\n", array_ptr[i]->values[num_values]);
X
X
X    if (EOF_there == EOF) {	/* No more data left.  Reset input
X				 * handler and main panel label */
X	notify_set_input_func(unique_handle, NOTIFY_FUNC_NULL, 0);
X	sprintf(&string[21], "%4d", num_values--);
X	panel_set(num_message, PANEL_LABEL_STRING, string, 0);
X	return (NOTIFY_DONE);
X    }
X    /* Last array is just record number */
X    array_ptr[num_arrays]->values[num_values] = num_values + 1;
X    array_ptr[num_arrays]->log_values[num_values] =
X	log10((double) num_values + 1);
X
X    /* Now update the graphs */
X    update_arrays();
X    update_displays();
X
X    return (NOTIFY_DONE);
X}
________This_Is_The_END________
if test `wc -l < pipe_reader.c` -ne 106; then
	echo -n 'shar: pipe_reader.c was damaged during transit'
	echo ' (should have been 106 bytes)'
fi
fi		; : end of overwriting check
echo 'x - quit_proc.c'
if test -f quit_proc.c
then echo 'shar: not overwriting quit_proc.c'; else
sed 's/^X//' << '________This_Is_The_END________' > quit_proc.c
X#include "trackertool.h"
X
Xint             client;		/* handle for input control */
Xvoid
Xquit_proc(button, event)
X    Panel_item      button;
X    Event          *event;
X /* Simply kills everything and leaves, or hides. */
X{
X    int             window_done();
X    int             i;
X    Notify_value    pipe_reader();
X
X    /* Turn off input notification (it causes asynch trouble */
X    notify_set_input_func(&client, NOTIFY_FUNC_NULL, 0);
X
X    /* Nice knowing ya */
X    if (!window_done(main_panel)) {	/* destroy may be vetoed */
X	notify_set_input_func(&client, pipe_reader, 0);
X	return;
X    }
X    /* If button was Quit, just leave.  Quickly. */
X    if (button == quit_button)
X	exit(0);
X
X    /*
X     * Replace process with a simple cat. Since Sunview needs to clean
X     * up, I can't very well just execl() quite yet.  Do a fork() and
X     * execl()/return.
X     */
X    if (fork() == 0)
X	return;			/* allow Sunview to cleanup
X				 * on return to main() */
X
X    /*
X     * The parent has gone home to clean up.  Let's keep the output
X     * going.
X     */
X    if (echo_on)
X	execl("/bin/cat", "cat", "-", 0);
X    else
X	execl("/bin/sh", "sh", "-c", "cat - > /dev/null", 0);
X
X    /* This function should never go anywhere after this,
X     * even if the execl fails.
X     */
X    exit(0);
X}
________This_Is_The_END________
if test `wc -l < quit_proc.c` -ne 48; then
	echo -n 'shar: quit_proc.c was damaged during transit'
	echo ' (should have been 48 bytes)'
fi
fi		; : end of overwriting check
echo 'x - repaint_canvas.c'
if test -f repaint_canvas.c
then echo 'shar: not overwriting repaint_canvas.c'; else
sed 's/^X//' << '________This_Is_The_END________' > repaint_canvas.c
X#include <stdio.h>
X#include <string.h>
X#include <math.h>
X#include "trackertool.h"
X
Xvoid
Xrepaint_canvas(canvas)
X    Canvas          canvas;
X{
X    Pixwin         *pw;
X    Subframe       *subframe_ptr;
X    Array          *x_ptr, *y_ptr;
X
X    /* Raster units */
X    int             i, ix, iy, jx, jy;
X    int             x_axis_min, x_axis_max, y_axis_min, y_axis_max;
X    int             width, height;
X    int             grid_line;
X
X    float           x_scale, y_scale;	/* coordinate to raster
X					 * conversion */
X    float          *x_value_ptr, *y_value_ptr;
X
X    /* Coordinate units */
X    float           x_min_graph, x_max_graph, y_min_graph, y_max_graph;
X    float           grid_min, grid_max, grid_delta, grid, grid_log_switch;
X
X    void            get_grid_bounds();
X    void            get_grid_log_bounds();
X
X    /* Axis label strings */
X    char            lab_x_min[15], lab_x_max[15], lab_y_min[15], lab_y_max[15];
X    int             len_x_min, len_x_max, len_y_min, len_y_max;
X    int             box_x, box_y;	/* font sizes */
X    struct pixfont *pf_used;	/* font for axis labels */
X    static struct pixfont *pf_small, *pf_medium, *pf_large;	/* keep fonts */
X
X
X    if (canvas == 0)
X	return;			/* canvas is not there */
X    pw = canvas_pixwin(canvas);	/* get the pixwin to draw into */
X
X    /* Find the subframe and x, y arrays for this canvas */
X    subframe_ptr = (Subframe *) window_get(canvas, WIN_CLIENT_DATA, 0);
X    x_ptr = subframe_ptr->x;
X    y_ptr = subframe_ptr->y;
X
X    /* get current canvas dimensions */
X    width = (int) window_get(canvas, CANVAS_WIDTH);
X    height = (int) window_get(canvas, CANVAS_HEIGHT);
X
X    /*
X     * Scale the axis label size to the dimensions. Some ugly magic
X     * numbers here, but hey, what do you want?
X     */
X    if (width < 150) {
X	if (pf_small == NULL)
X	    pf_small = pf_open("/usr/lib/fonts/fixedwidthfonts/screen.r.7");
X	pf_used = pf_small;
X	box_x = pf_small->pf_defaultsize.x;
X	box_y = pf_small->pf_defaultsize.y + 2;
X    } else if (width < 350) {
X	if (pf_medium == NULL)
X	    pf_medium = pf_open("/usr/lib/fonts/fixedwidthfonts/screen.r.11");
X	pf_used = pf_medium;
X	box_x = pf_medium->pf_defaultsize.x;
X	box_y = pf_medium->pf_defaultsize.y + 2;
X    } else {
X	if (pf_large == NULL)
X	    pf_large = pf_open("/usr/lib/fonts/fixedwidthfonts/gallant.r.19");
X	pf_used = pf_large;
X	box_x = pf_large->pf_defaultsize.x;
X	box_y = pf_large->pf_defaultsize.y + 2;
X    }
X
X    /* Clear the canvas */
X    pw_writebackground(pw, 0, 0, width, height, PIX_SRC);
X
X    /*
X     * Find new axis limits for the auto limits. The axis limits might
X     * have changed between redraws, or they might be fixed by the
X     * panel when _auto turned off
X     */
X    if (subframe_ptr->x_log) {
X	if (subframe_ptr->x_min_auto)
X	    subframe_ptr->x_min = x_ptr->min_graph_log;
X	if (subframe_ptr->x_max_auto)
X	    subframe_ptr->x_max = x_ptr->max_graph_log;
X    } else {
X	if (subframe_ptr->x_min_auto)
X	    subframe_ptr->x_min = x_ptr->min_graph;
X	if (subframe_ptr->x_max_auto)
X	    subframe_ptr->x_max = x_ptr->max_graph;
X    }
X    if (subframe_ptr->y_log) {
X	if (subframe_ptr->y_min_auto)
X	    subframe_ptr->y_min = y_ptr->min_graph_log;
X	if (subframe_ptr->y_max_auto)
X	    subframe_ptr->y_max = y_ptr->max_graph_log;
X    } else {
X	if (subframe_ptr->y_min_auto)
X	    subframe_ptr->y_min = y_ptr->min_graph;
X	if (subframe_ptr->y_max_auto)
X	    subframe_ptr->y_max = y_ptr->max_graph;
X    }
X    /* get the axis labels and lengths in pixels */
X    len_x_min = strlen(gcvt(subframe_ptr->x_min, 5, lab_x_min)) * box_x + 2;
X    len_x_max = strlen(gcvt(subframe_ptr->x_max, 5, lab_x_max)) * box_x + 2;
X    len_y_min = strlen(gcvt(subframe_ptr->y_min, 5, lab_y_min)) * box_x + 2;
X    len_y_max = strlen(gcvt(subframe_ptr->y_max, 5, lab_y_max)) * box_x + 2;
X
X    /* Find axis limits in pixels and draw them */
X    x_axis_min = (len_y_min > len_y_max) ? len_y_min : len_y_max;
X    x_axis_min = (len_x_min / 2 > x_axis_min) ? len_x_min / 2 : x_axis_min;
X    x_axis_max = width - 2;
X    y_axis_min = height - box_y - 3;
X    y_axis_max = 2;
X    pw_vector(pw, x_axis_min, y_axis_max, x_axis_min, y_axis_min, PIX_SRC, 1);
X    pw_vector(pw, x_axis_min, y_axis_min, x_axis_max, y_axis_min, PIX_SRC, 1);
X    subframe_ptr->x_axis_min = x_axis_min;
X    subframe_ptr->x_axis_max = x_axis_max;
X    subframe_ptr->y_axis_min = y_axis_min;
X    subframe_ptr->y_axis_max = y_axis_max;
X
X    /* Put the new axis limits on the canvas */
X    pw_text(pw, x_axis_min - len_x_min / 2, y_axis_min + box_y,
X	PIX_SRC, pf_used, lab_x_min);
X    pw_text(pw, x_axis_max - len_x_max, y_axis_min + box_y,
X	PIX_SRC, pf_used, lab_x_max);
X    pw_text(pw, x_axis_min - len_y_min, y_axis_min,
X	PIX_SRC, pf_used, lab_y_min);
X    pw_text(pw, x_axis_min - len_y_max, y_axis_max + box_y - 2,
X	PIX_SRC, pf_used, lab_y_max);
X
X    /* If control panel not there, put axis label on canvas */
X    if (!subframe_ptr->panel) {
X	pw_text(pw, width / 2, y_axis_min + box_y,
X	    PIX_SRC, pf_used, x_ptr->label_l);
X	pw_text(pw, width / 2, y_axis_max + box_y - 2,
X	    PIX_SRC, pf_used, y_ptr->label_l);
X    }
X    /*
X     * finalize linear, log axis limits here.  Also, set up the
X     * pointers to the array values.
X     */
X    if (subframe_ptr->x_log) {
X	if (subframe_ptr->x_min <= 0.) {
X	    pw_text(pw, width / 5, height / 5, PIX_SRC, NULL,
X		"x_min < 0; Log invalid");
X	    return;
X	}
X	x_value_ptr = x_ptr->log_values;
X	x_min_graph = log10(subframe_ptr->x_min);
X	x_max_graph = log10(subframe_ptr->x_max);
X    } else {
X	x_value_ptr = x_ptr->values;
X	x_min_graph = subframe_ptr->x_min;
X	x_max_graph = subframe_ptr->x_max;
X    }
X    if (subframe_ptr->y_log) {
X	if (subframe_ptr->y_min <= 0.) {
X	    pw_text(pw, width / 5, height / 5, PIX_SRC, NULL,
X		"y_min < 0; Log invalid");
X	    return;
X	}
X	y_value_ptr = y_ptr->log_values;
X	y_min_graph = log10(subframe_ptr->y_min);
X	y_max_graph = log10(subframe_ptr->y_max);
X    } else {
X	y_value_ptr = y_ptr->values;
X	y_min_graph = subframe_ptr->y_min;
X	y_max_graph = subframe_ptr->y_max;
X    }
X
X    /* Draw the actual data now */
X    x_scale = (x_axis_max - x_axis_min) / (x_max_graph - x_min_graph);
X    y_scale = (y_axis_max - y_axis_min) / (y_max_graph - y_min_graph);
X    ix = (*x_value_ptr - x_min_graph) * x_scale + x_axis_min;
X    iy = (*y_value_ptr - y_min_graph) * y_scale + y_axis_min;
X
X    pw_batch_on(pw);
X
X    for (i = subframe_ptr->connect_points; i <= num_values; i++) {
X	jx = (*(++x_value_ptr) - x_min_graph) * x_scale + x_axis_min;
X	jy = (*(++y_value_ptr) - y_min_graph) * y_scale + y_axis_min;
X
X	if (subframe_ptr->connect_points) {
X	    pw_vector(pw, ix, iy, jx, jy, PIX_SRC, 1);
X	    ix = jx;
X	    iy = jy;
X	} else
X	    pw_put(pw, jx, jy, 1);
X
X    }
X
X    /* Draw x grid */
X    if (subframe_ptr->x_grid) {
X	if (subframe_ptr->x_log) {	/* Logarithmic grid lines */
X	    get_grid_log_bounds(x_min_graph, x_max_graph,
X		&grid_min, &grid_max, &grid_delta, &grid_log_switch);
X	    for (grid = grid_min; grid < grid_max; grid = grid + grid_delta) {
X		if (grid > grid_log_switch) {	/* Need to change grid
X						 * spacing */
X		    grid_delta *= 10.;
X		    grid = 2. * grid_delta;
X		    grid_log_switch *= 10.;
X		}
X		grid_line = (log10(grid) - x_min_graph) * x_scale
X			+ x_axis_min + 0.5;
X		pw_vector(pw, grid_line, y_axis_min,
X			grid_line, y_axis_max, PIX_SRC, 1);
X	    }
X	} else {		/* Normal grid lines */
X	    get_grid_bounds(x_min_graph, x_max_graph,
X		&grid_min, &grid_max, &grid_delta);
X	    for (grid = grid_min; grid < grid_max; grid = grid + grid_delta) {
X		grid_line = (grid - x_min_graph) * x_scale + x_axis_min + 0.5;
X		pw_vector(pw, grid_line, y_axis_min,
X			grid_line, y_axis_max, PIX_SRC, 1);
X	    }
X	}
X    }
X    /* Draw y grid */
X    if (subframe_ptr->y_grid) {
X	if (subframe_ptr->y_log) {	/* Logarithmic grid lines */
X	    get_grid_log_bounds(y_min_graph, y_max_graph,
X		&grid_min, &grid_max, &grid_delta, &grid_log_switch);
X	    for (grid = grid_min; grid < grid_max; grid = grid + grid_delta) {
X		if (grid > grid_log_switch) {	/* Need to change grid
X						 * spacing */
X		    grid_delta *= 10.;
X		    grid = 2. * grid_delta;
X		    grid_log_switch *= 10.;
X		}
X		grid_line = (log10(grid) - y_min_graph) * y_scale
X			+ y_axis_min + 0.5;
X		pw_vector(pw, x_axis_min, grid_line,
X			x_axis_max, grid_line, PIX_SRC, 1);
X	    }
X	} else {		/* Normal grid lines */
X	    get_grid_bounds(y_min_graph, y_max_graph,
X		&grid_min, &grid_max, &grid_delta);
X	    for (grid = grid_min; grid < grid_max; grid = grid + grid_delta) {
X		grid_line = (grid - y_min_graph) * y_scale + y_axis_min + 0.5;
X		pw_vector(pw, x_axis_min, grid_line,
X			x_axis_max, grid_line, PIX_SRC, 1);
X	    }
X	}
X    }
X    pw_batch_off(pw);
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < repaint_canvas.c` -ne 253; then
	echo -n 'shar: repaint_canvas.c was damaged during transit'
	echo ' (should have been 253 bytes)'
fi
fi		; : end of overwriting check
echo 'x - reset_axis_proc.c'
if test -f reset_axis_proc.c
then echo 'shar: not overwriting reset_axis_proc.c'; else
sed 's/^X//' << '________This_Is_The_END________' > reset_axis_proc.c
X#include "trackertool.h"
X
Xvoid
Xreset_axis_proc(button)
X    Panel_item      button;
X/*
X * On reset:  resets the axis descriptors to the default values
X * On redraw: get the panel's text strings and redraw
X */
X{
X    Panel           panel;
X    Subframe       *subframe_ptr;
X    Panel_item      next_item;
X    void            repaint_canvas();
X    double          atof();
X
X    panel = (Panel) panel_get(button, PANEL_PARENT_PANEL);
X    subframe_ptr = (Subframe *) window_get(panel, WIN_CLIENT_DATA, 0);
X
X    if ((int) panel_get(button, PANEL_CLIENT_DATA)) {
X	subframe_ptr->x_min_auto = TRUE;
X	subframe_ptr->x_max_auto = TRUE;
X	subframe_ptr->x_log = FALSE;
X	subframe_ptr->x_grid = FALSE;
X	subframe_ptr->y_min_auto = TRUE;
X	subframe_ptr->y_max_auto = TRUE;
X	subframe_ptr->y_log = FALSE;
X	subframe_ptr->y_grid = FALSE;
X	subframe_ptr->connect_points = TRUE;
X
X	/* reset the panel: draw mode, and x,y atributes */
X	next_item = window_get(panel, PANEL_FIRST_ITEM, 0);
X	panel_set_value(next_item, TRUE);	/* draw mode to connect */
X	next_item = panel_get(next_item, PANEL_NEXT_ITEM, 0);
X	panel_set_value(next_item, 3);	/* x attributes */
X	next_item = panel_get(next_item, PANEL_NEXT_ITEM, 0);
X	panel_set_value(next_item, 3);	/* y attributes */
X    } else {
X	/* get the panel values again if redraw requested */
X	if (!subframe_ptr->x_min_auto)
X	    subframe_ptr->x_min = atof(
X		(char *) panel_get_value(subframe_ptr->props_x_min));
X	if (!subframe_ptr->x_max_auto)
X	    subframe_ptr->x_max = atof(
X		(char *) panel_get_value(subframe_ptr->props_x_max));
X	if (!subframe_ptr->y_min_auto)
X	    subframe_ptr->y_min = atof(
X		(char *) panel_get_value(subframe_ptr->props_y_min));
X	if (!subframe_ptr->y_max_auto)
X	    subframe_ptr->y_max = atof(
X		(char *) panel_get_value(subframe_ptr->props_y_max));
X    }
X
X    repaint_canvas(subframe_ptr->canvas);
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < reset_axis_proc.c` -ne 57; then
	echo -n 'shar: reset_axis_proc.c was damaged during transit'
	echo ' (should have been 57 bytes)'
fi
fi		; : end of overwriting check
echo 'x - rewrite_text.c'
if test -f rewrite_text.c
then echo 'shar: not overwriting rewrite_text.c'; else
sed 's/^X//' << '________This_Is_The_END________' > rewrite_text.c
X#include <string.h>
X#include "trackertool.h"
X
Xvoid
Xrewrite_text(textsw)
X    Textsw          textsw;
X{
X    /*
X     * rewrite_text will create a new text from scratch. It will delete
X     * whatever text is already there, which is needed in the case of
X     * variable changes.
X     */
X    Subframe       *subframe_ptr;
X    char            string[2 * MAX_STR_LEN + 4];
X    char           *buffer, *buf_counter;
X    int             i;
X
X    if (textsw == 0)
X	return;			/* textsw is not there */
X
X    /* Find the subframe we're in */
X    subframe_ptr = (Subframe *) window_get(textsw, WIN_CLIENT_DATA, 0);
X
X    textsw_reset(textsw, 0, 0);	/* Delete current text */
X
X    /* Construct label line */
X    strncpy(&string[0], "  ", 2);
X    strncpy(&string[2], subframe_ptr->x->label_r, MAX_STR_LEN - 1);
X    strncpy(&string[MAX_STR_LEN + 1], "   ", 3);
X    strncpy(&string[MAX_STR_LEN + 4], subframe_ptr->y->label_r,
X	MAX_STR_LEN - 1);
X    textsw_insert(textsw, string, 2 * MAX_STR_LEN + 3);
X
X    /*
X     * Now put in the data.  We allocate a buffer big enough for all
X     * the characters, place them in, and hand it to textsw_insert.
X     * This is much faster than multiple inserts.
X     */
X    buffer = (char *) malloc(26 * (num_values + 1) * sizeof(char));
X    buf_counter = buffer;
X    for (i = 0; i <= num_values; i++) {
X	sprintf(buf_counter, "\n%12g %12g",
X	    subframe_ptr->x->values[i], subframe_ptr->y->values[i]);
X	buf_counter += 26;
X    }
X    textsw_insert(textsw, buffer, 26 * (num_values + 1));
X    free(buffer);
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < rewrite_text.c` -ne 50; then
	echo -n 'shar: rewrite_text.c was damaged during transit'
	echo ' (should have been 50 bytes)'
fi
fi		; : end of overwriting check
echo 'x - trackertool.c'
if test -f trackertool.c
then echo 'shar: not overwriting trackertool.c'; else
sed 's/^X//' << '________This_Is_The_END________' > trackertool.c
X#include "stdio.h"
X#include "trackertool.h"
X
X/* Trackertool, Version 1.0, November 1988
X *
X *
X * Copyright (c) 1988 Roy Richter, GM Corp.  Anyone can use this
X *  software in any manner they choose, including copying, modification
X *  and redistribution, provided they make no charge for it, the source
X *  code is included in the distribution, and these conditions remain
X *  unchanged.
X
X * 
X *  This program is distributed as is, with all faults (if any), and
X *  without any warranty. No author or distributor accepts responsibility
X *  to anyone for the consequences of using it, or for whether it serves
X *  any particular purpose at all, or any other reason.
X * 
X */
X
Xint             client;		/* handle for input control */
X
Xmain(argc, argv)
X    int             argc;
X    char          **argv;
X{
X    Frame           make_base(), base_frame;
X    void            make_labels();
X    Notify_value    pipe_reader();
X
X    int             process_group;
X
X    int             c;		/* to hold arguments  from getopt */
X    extern int      opterr;	/* getopt's error checking */
X    extern char    *optarg;	/* getopt's return value */
X
X    /*
X     * I'm keeping track of the file descriptors to prevent overusage.
X     * This is the real limit to the number of open windows. 3 (unix)
X     * +1 (framebuffer) +4 (selection service) +1 (window manager) +1
X     * (good luck)
X     */
X    num_fd = 10;
X
X    /* get the command line arguments, if any. */
X    opterr = 0;			/* ignore options we don't recognize */
X    MAX_VALUES = DEFAULT_MAX_VALUES;	/* set defaults */
X    echo_on = TRUE;		/* echo input to output */
X    while ((c = getopt(argc, argv, "nv:")) != EOF)
X	switch (c) {
X	case 'v':		/* increase MAX_VALUES */
X	    MAX_VALUES = atoi(optarg);
X	    if (MAX_VALUES < 2 || MAX_VALUES > 100000) {
X		fprintf(stderr, "-v %s = %d out of range.\n",
X			optarg, MAX_VALUES);
X		fprintf(stderr, "Allowable range is 2 to 100,000.  ");
X		fprintf(stderr, "Defaulting to %d.\n", DEFAULT_MAX_VALUES);
X		MAX_VALUES = DEFAULT_MAX_VALUES;
X	    }
X	    break;
X	case 'n':		/* don't echo input to output */
X	    echo_on = FALSE;
X	    break;
X	case '?':
X	    break;		/* ignore others */
X	}
X
X    /*
X     * get the current process group. It needs to be reset after each
X     * window_create to allow dbxtool to work.
X     */
X    process_group = getpgrp(0);
X
X    /* Create the base frame window */
X    base_frame = make_base(argc, argv);
X
X    /* now set the process group */
X    setpgrp(0, process_group);
X
X    /* Get the label line from stdin and initialize labels */
X    make_labels();
X
X    /* Tell the notifier what to do when input is received */
X    (void) notify_set_input_func(&client, pipe_reader, 0);
X
X    /*
X     * Start notifier to grab button pushes, etc. We return from this
X     * call when quit is pressed. and quit_proc is called.
X     */
X    window_main_loop(base_frame);
X}
________This_Is_The_END________
if test `wc -l < trackertool.c` -ne 91; then
	echo -n 'shar: trackertool.c was damaged during transit'
	echo ' (should have been 91 bytes)'
fi
fi		; : end of overwriting check
echo 'x - update_arrays.c'
if test -f update_arrays.c
then echo 'shar: not overwriting update_arrays.c'; else
sed 's/^X//' << '________This_Is_The_END________' > update_arrays.c
X#include "trackertool.h"
X
Xvoid
Xupdate_arrays()
X{
X    /* updates the array tables when a new value is added */
X    int             i;
X    float           value;
X
X    void            get_axis_bounds();
X    void            get_axis_log_bounds();
X
X    /*
X     * Update the actual min, max values; and then check to see if we
X     * need to change the graph limits
X     */
X    if (num_values)		/* Not first time through? */
X	for (i = 0; i <= num_arrays; i++) {
X	    value = array_ptr[i]->values[num_values];
X
X	    /* Update min, max values and possibly axis limits */
X	    if (array_ptr[i]->min_value > value)
X		array_ptr[i]->min_value = value;
X	    if (array_ptr[i]->max_value < value)
X		array_ptr[i]->max_value = value;
X	    if (array_ptr[i]->min_value < array_ptr[i]->min_graph ||
X		array_ptr[i]->max_value > array_ptr[i]->max_graph)
X		get_axis_bounds(array_ptr[i]->min_value,
X		    array_ptr[i]->max_value,
X		    &(array_ptr[i]->min_graph),
X		    &(array_ptr[i]->max_graph));
X
X	    /* keep minimum positive value for log bound */
X	    if ((array_ptr[i]->min_value_log > value ||
X		    array_ptr[i]->min_value_log == 0) && value > 0.)
X		array_ptr[i]->min_value_log = value;
X	    if (array_ptr[i]->min_value_log < array_ptr[i]->min_graph_log ||
X		array_ptr[i]->max_value > array_ptr[i]->max_graph_log)
X		get_axis_log_bounds(array_ptr[i]->min_value_log,
X		    array_ptr[i]->max_value,
X		    &(array_ptr[i]->min_graph_log),
X		    &(array_ptr[i]->max_graph_log));
X	}
X    else
X	/* case for num_values = 0; this is first time through */
X	for (i = 0; i <= num_arrays; i++) {
X	    value = array_ptr[i]->values[num_values];
X	    array_ptr[i]->min_value = value;
X	    array_ptr[i]->max_value = value;
X	    array_ptr[i]->min_graph = value;
X	    array_ptr[i]->max_value = value;
X	    if (value > 0.) {
X		array_ptr[i]->min_value_log = value;
X		array_ptr[i]->min_graph_log = value;
X		array_ptr[i]->max_graph_log = value;
X	    } else {
X		array_ptr[i]->min_value_log = 0.;
X		array_ptr[i]->min_graph_log = 1e22;
X		array_ptr[i]->max_graph_log = 1e-22;
X	    }
X	}
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < update_arrays.c` -ne 64; then
	echo -n 'shar: update_arrays.c was damaged during transit'
	echo ' (should have been 64 bytes)'
fi
fi		; : end of overwriting check
echo 'x - update_canvas.c'
if test -f update_canvas.c
then echo 'shar: not overwriting update_canvas.c'; else
sed 's/^X//' << '________This_Is_The_END________' > update_canvas.c
X#include <math.h>
X#include "trackertool.h"
X
Xvoid
Xupdate_canvas(canvas)
X    Canvas          canvas;
X /* Adds a line segment to the given canvas */
X{
X    Pixwin         *pw;
X    Subframe       *subframe_ptr;
X    Array          *x_ptr, *y_ptr;
X
X    int             ix, iy, jx, jy;
X    int             x_axis_min, x_axis_max, y_axis_min, y_axis_max;
X    float           x_scale, y_scale;
X    float          *x_value_ptr, *y_value_ptr;
X    float           x_min_graph, x_max_graph, y_min_graph, y_max_graph;
X
X    if (num_values == 0)
X	return;			/* can't draw one point */
X    if (canvas == 0)
X	return;			/* canvas is not there  */
X
X    /* Get the pixwin to draw into */
X    pw = canvas_pixwin(canvas);
X
X    /* Find the subframe and x, y arrays for this canvas */
X    subframe_ptr = (Subframe *) window_get(canvas, WIN_CLIENT_DATA, 0);
X    x_ptr = subframe_ptr->x;
X    y_ptr = subframe_ptr->y;
X
X    /* Find axis limits */
X    x_axis_min = subframe_ptr->x_axis_min;
X    x_axis_max = subframe_ptr->x_axis_max;
X    y_axis_min = subframe_ptr->y_axis_min;
X    y_axis_max = subframe_ptr->y_axis_max;
X
X    if (subframe_ptr->x_log) {
X	x_value_ptr = &(x_ptr->log_values[num_values - 1]);
X	x_min_graph = log10(subframe_ptr->x_min);
X	x_max_graph = log10(subframe_ptr->x_max);
X    } else {
X	x_value_ptr = &(x_ptr->values[num_values - 1]);
X	x_min_graph = subframe_ptr->x_min;
X	x_max_graph = subframe_ptr->x_max;
X    }
X    if (subframe_ptr->y_log) {
X	y_value_ptr = &(y_ptr->log_values[num_values - 1]);
X	y_min_graph = log10(subframe_ptr->y_min);
X	y_max_graph = log10(subframe_ptr->y_max);
X    } else {
X	y_value_ptr = &(y_ptr->values[num_values - 1]);
X	y_min_graph = subframe_ptr->y_min;
X	y_max_graph = subframe_ptr->y_max;
X    }
X
X    /* Draw the actual data now */
X    x_scale = (x_axis_max - x_axis_min) / (x_max_graph - x_min_graph);
X    y_scale = (y_axis_max - y_axis_min) / (y_max_graph - y_min_graph);
X
X    ix = (*(x_value_ptr++) - x_min_graph) * x_scale + x_axis_min;
X    iy = (*(y_value_ptr++) - y_min_graph) * y_scale + y_axis_min;
X    jx = (*x_value_ptr - x_min_graph) * x_scale + x_axis_min;
X    jy = (*y_value_ptr - y_min_graph) * y_scale + y_axis_min;
X
X    if (subframe_ptr->connect_points)
X	pw_vector(pw, ix, iy, jx, jy, PIX_SRC, 1);
X    else
X	pw_put(pw, jx, jy, 1);
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < update_canvas.c` -ne 72; then
	echo -n 'shar: update_canvas.c was damaged during transit'
	echo ' (should have been 72 bytes)'
fi
fi		; : end of overwriting check
echo 'x - update_displays.c'
if test -f update_displays.c
then echo 'shar: not overwriting update_displays.c'; else
sed 's/^X//' << '________This_Is_The_END________' > update_displays.c
X#include <stdio.h>
X#include "trackertool.h"
X
Xvoid
Xupdate_displays()
X/* update_displays will incrementally update the displays in progress
X */
X{
X    void            update_textsw();
X    void            update_canvas();
X    void            repaint_canvas();
X
X    static char     string[26] = {"Reading..... Values:    0"};
X    float           x_min, x_max, y_min, y_max;
X    Subframe       *subframe_ptr, **sub_ptr_ptr, **sub_ptr_max;
X
X    sprintf(&string[21], "%4d", num_values + 1);
X    panel_set(num_message, PANEL_LABEL_STRING, string, 0);
X
X    sub_ptr_max = subframe + num_of_subframes;
X    for (sub_ptr_ptr = subframe; sub_ptr_ptr <= sub_ptr_max; sub_ptr_ptr++) {
X	subframe_ptr = *sub_ptr_ptr;
X	update_textsw(subframe_ptr->textsw);
X
X	/* {x,y}_{min,max} contains the current array limits. */
X	if (subframe_ptr->x_log) {
X	    x_min = subframe_ptr->x->min_graph_log;
X	    x_max = subframe_ptr->x->max_graph_log;
X	} else {
X	    x_min = subframe_ptr->x->min_graph;
X	    x_max = subframe_ptr->x->max_graph;
X	}
X	if (subframe_ptr->y_log) {
X	    y_min = subframe_ptr->y->min_graph_log;
X	    y_max = subframe_ptr->y->max_graph_log;
X	} else {
X	    y_min = subframe_ptr->y->min_graph;
X	    y_max = subframe_ptr->y->max_graph;
X	}
X
X	/* test here to see if we need to rescale the axis limits */
X	if ((x_min < subframe_ptr->x_min && subframe_ptr->x_min_auto) ||
X	    (x_max > subframe_ptr->x_max && subframe_ptr->x_max_auto) ||
X	    (y_min < subframe_ptr->y_min && subframe_ptr->y_min_auto) ||
X	    (y_max > subframe_ptr->y_max && subframe_ptr->y_max_auto))
X	    repaint_canvas(subframe_ptr->canvas);
X	else
X	    update_canvas(subframe_ptr->canvas);
X    }
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < update_displays.c` -ne 52; then
	echo -n 'shar: update_displays.c was damaged during transit'
	echo ' (should have been 52 bytes)'
fi
fi		; : end of overwriting check
echo 'x - update_textsw.c'
if test -f update_textsw.c
then echo 'shar: not overwriting update_textsw.c'; else
sed 's/^X//' << '________This_Is_The_END________' > update_textsw.c
X#include <stdio.h>
X#include "trackertool.h"
X
Xvoid
Xupdate_textsw(textsw)
X    Textsw          textsw;
X/* Add a line to the given textsw */
X{
X    Subframe       *subframe_ptr;
X    char            string[2 * MAX_STR_LEN + 4];
X
X    if (textsw == 0)
X	return;			/* textsw is not there */
X
X    /* Find the subframe we're in */
X    subframe_ptr = (Subframe *) window_get(textsw, WIN_CLIENT_DATA, 0);
X
X    /* Construct line */
X    sprintf(string, "\n%12g %12g", subframe_ptr->x->values[num_values],
X	subframe_ptr->y->values[num_values]);
X
X    /* Insert the line at the current insertion point */
X    textsw_insert(textsw, string, 2 * MAX_STR_LEN + 4);
X
X    return;
X}
________This_Is_The_END________
if test `wc -l < update_textsw.c` -ne 26; then
	echo -n 'shar: update_textsw.c was damaged during transit'
	echo ' (should have been 26 bytes)'
fi
fi		; : end of overwriting check
echo 'x - zoom_event.c'
if test -f zoom_event.c
then echo 'shar: not overwriting zoom_event.c'; else
sed 's/^X//' << '________This_Is_The_END________' > zoom_event.c
X#include "trackertool.h"
X#include <math.h>
X
XNotify_value
Xzoom_event(canvas, event)
X    Canvas          canvas;
X    Event          *event;
X{
X    /*
X     * zoom_event is used to zoom the picture in a graph It picks up
X     * the events turned on when th canvas was created You put the left
X     * button down, and rectangle is created; as the mouse is moved,
X     * the rectangle follows the mouse; when the buttonis released, the
X     * final bounding coordinates are used to reset the axis bounds.
X     */
X    Pixwin         *pw;
X    static int      x0, y0, x1, y1;
X    static int      box_started = FALSE;
X    int             id;
X    void            make_box(), set_axis_bounds();
X
X    id = event_id(event);
X    pw = canvas_pixwin(canvas);
X
X    /* Follow the bounding box, if started */
X    if (id == LOC_MOVE && box_started) {
X	make_box(pw, x0, y0, x1, y1);
X	x1 = event_x(event);
X	y1 = event_y(event);
X	make_box(pw, x0, y0, x1, y1);
X	return;
X    }
X    /* Only the left button is active */
X    if (id != MS_LEFT)
X	return;
X
X    /* The initial button push is caught here */
X    if (event_is_down(event) && !box_started) {
X	x0 = event_x(event);
X	y0 = event_y(event);
X	x1 = x0;
X	y1 = y0;
X	make_box(pw, x0, y0, x1, y1);
X	box_started = TRUE;
X	return;
X    }
X    /* Final button release is caught here */
X    if (event_is_up(event) && box_started) {
X	make_box(pw, x0, y0, x1, y1);
X	x1 = event_x(event);
X	y1 = event_y(event);
X	box_started = FALSE;
X	set_axis_bounds(canvas, x0, y1, x1, y0);
X	return;
X    }
X    return;
X}
X
Xvoid
Xmake_box(pw, x0, y0, x1, y1)
X    Pixwin         *pw;
X    int             x0, y0, x1, y1;
X{
X    /*
X     * make_box will invert the pixels given in the bounding box.  Use
X     * it to write and erase a rubber-band box from make_box.
X     */
X    pw_vector(pw, x0, y0, x1, y0, PIX_NOT(PIX_DST), 1);
X    pw_vector(pw, x1, y0, x1, y1, PIX_NOT(PIX_DST), 1);
X    pw_vector(pw, x1, y1, x0, y1, PIX_NOT(PIX_DST), 1);
X    pw_vector(pw, x0, y1, x0, y0, PIX_NOT(PIX_DST), 1);
X
X    return;
X}
X
Xvoid
Xset_axis_bounds(canvas, x_min, y_min, x_max, y_max)
X    Canvas          canvas;
X    int             x_min, y_min, x_max, y_max;
X{
X    /*
X     * Enforce a set of bounds, given in pixels, on the graph in
X     * canvas.
X     */
X    Subframe       *subframe_ptr;
X    float           x_min_new, x_max_new, y_min_new, y_max_new;
X
X    char           *gcvt(), buf[18];
X    void            repaint_canvas();
X    Panel_item      item;
X
X    /* Find all the appropriate pointers */
X    subframe_ptr = (Subframe *) window_get(canvas, WIN_CLIENT_DATA, 0);
X
X    /* Convert the values from pixel to data coordinates */
X    if (subframe_ptr->x_log) {
X	x_min_new = (x_min - subframe_ptr->x_axis_min) *
X	    (log10(subframe_ptr->x_max) - log10(subframe_ptr->x_min)) /
X	    (subframe_ptr->x_axis_max - subframe_ptr->x_axis_min) +
X	    log10(subframe_ptr->x_min);
X	x_max_new = (x_max - subframe_ptr->x_axis_min) *
X	    (log10(subframe_ptr->x_max) - log10(subframe_ptr->x_min)) /
X	    (subframe_ptr->x_axis_max - subframe_ptr->x_axis_min) +
X	    log10(subframe_ptr->x_min);
X	x_min_new = pow(10., x_min_new);
X	x_max_new = pow(10., x_max_new);
X    } else {
X	x_min_new = (x_min - subframe_ptr->x_axis_min) *
X	    (subframe_ptr->x_max - subframe_ptr->x_min) /
X	    (subframe_ptr->x_axis_max - subframe_ptr->x_axis_min) +
X	    subframe_ptr->x_min;
X	x_max_new = (x_max - subframe_ptr->x_axis_min) *
X	    (subframe_ptr->x_max - subframe_ptr->x_min) /
X	    (subframe_ptr->x_axis_max - subframe_ptr->x_axis_min) +
X	    subframe_ptr->x_min;
X    }
X    if (subframe_ptr->y_log) {
X	y_min_new = (y_min - subframe_ptr->y_axis_min) *
X	    (log10(subframe_ptr->y_max) - log10(subframe_ptr->y_min)) /
X	    (subframe_ptr->y_axis_max - subframe_ptr->y_axis_min) +
X	    log10(subframe_ptr->y_min);
X	y_max_new = (y_max - subframe_ptr->y_axis_min) *
X	    (log10(subframe_ptr->y_max) - log10(subframe_ptr->y_min)) /
X	    (subframe_ptr->y_axis_max - subframe_ptr->y_axis_min) +
X	    log10(subframe_ptr->y_min);
X	y_min_new = pow(10., y_min_new);
X	y_max_new = pow(10., y_max_new);
X    } else {
X	y_min_new = (y_min - subframe_ptr->y_axis_min) *
X	    (subframe_ptr->y_max - subframe_ptr->y_min) /
X	    (subframe_ptr->y_axis_max - subframe_ptr->y_axis_min) +
X	    subframe_ptr->y_min;
X	y_max_new = (y_max - subframe_ptr->y_axis_min) *
X	    (subframe_ptr->y_max - subframe_ptr->y_min) /
X	    (subframe_ptr->y_axis_max - subframe_ptr->y_axis_min) +
X	    subframe_ptr->y_min;
X    }
X
X    /* Update the props toggles to prevent overwriting */
X    if (subframe_ptr->props) {
X	panel_set_value(subframe_ptr->props_x_min, gcvt(x_min_new, 8, buf));
X	panel_set_value(subframe_ptr->props_x_max, gcvt(x_max_new, 8, buf));
X	panel_set_value(subframe_ptr->props_y_min, gcvt(y_min_new, 8, buf));
X	panel_set_value(subframe_ptr->props_y_max, gcvt(y_max_new, 8, buf));
X	item = (Panel_item) window_get(subframe_ptr->props, PANEL_FIRST_ITEM);
X	item = (Panel_item) panel_get(item, PANEL_NEXT_ITEM);
X	panel_set(item, PANEL_TOGGLE_VALUE, 0, FALSE,
X	    PANEL_TOGGLE_VALUE, 1, FALSE, 0);
X	item = (Panel_item) panel_get(item, PANEL_NEXT_ITEM);
X	panel_set(item, PANEL_TOGGLE_VALUE, 0, FALSE,
X	    PANEL_TOGGLE_VALUE, 1, FALSE, 0);
X    }
X    /* Set the values in the structures */
X    subframe_ptr->x_min_auto = FALSE;
X    subframe_ptr->x_max_auto = FALSE;
X    subframe_ptr->y_min_auto = FALSE;
X    subframe_ptr->y_max_auto = FALSE;
X    subframe_ptr->x_min = x_min_new;
X    subframe_ptr->x_max = x_max_new;
X    subframe_ptr->y_min = y_min_new;
X    subframe_ptr->y_max = y_max_new;
X
X    /* Finally, rescale the graph */
X    repaint_canvas(canvas);
X
X    return;
X
X/* Trackertool, Version 1.0, November 1988
X *
X *
X * Copyright (c) 1988 Roy Richter, GM Corp.  Anyone can use this
X *  software in any manner they choose, including copying, modification
X *  and redistribution, provided they make no charge for it, the source
X *  code is included in the distribution, and these conditions remain
X *  unchanged.
X
X * 
X *  This program is distributed as is, with all faults (if any), and
X *  without any warranty. No author or distributor accepts responsibility
X *  to anyone for the consequences of using it, or for whether it serves
X *  any particular purpose at all, or any other reason.
X * 
X */
X}
________This_Is_The_END________
if test `wc -l < zoom_event.c` -ne 184; then
	echo -n 'shar: zoom_event.c was damaged during transit'
	echo ' (should have been 184 bytes)'
fi
fi		; : end of overwriting check
exit 0
-- 
Roy Richter                  UUCP:  {sharkey,edsews,cfctech}!rphroy!rrichter
Physics Dept, GM Research    CSNet: rrichter@gmr.com
                             Internet: rrichter%rphroy.uucp@mailgw.cc.umich.edu