

/**************************************************************************
 *                                                                        *
 * Copyright (c) 1996 Michael Richmond and Richard Treffers               *
 *                                                                        *
 *                    This software may be copied and distributed for     *
 *                    educational, research and not for profit services   *
 *                    provided that this copyright and statement are      *
 *                    included in all such copies.                        *
 *                                                                        *
 **************************************************************************/


/*	
	Places markers on the tv images

	marks [file] [echo] [num=] [row=] [col=] [help]

	12/09/92 - added file input and line skipping for number option
			blasted to bits
	12/29/92 - changed input line from NBUF to BIG_BUF
	11/17/93 - add marks: to error message
	1/7/96   - removed the obsolete 'number' option. MWR
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "pcvista.h"
#include "ctype.h"
#include "usleep.h"

#define XWINDOWS

#ifdef PROTO
int main(int, char **);
static void show_options(void);
static int do_mark(int,int,int,int);
#else
static void show_options();
#endif

#ifdef XWINDOWS
#include <signal.h>
#include "pcvistax.h"
static void sig_trap(int);
#endif


char *progname = "marks";

int 
main(argc, argv)
int argc;
char *argv[];
{
	int i,row,col,other;
	int rowcol, colcol, numcol;
	char *gotit, buf[BIG_BUF];
	int mode=STATE_CROSSHAIR;
	static int echo_flag;
	FILE *fin=stdin;

	/* placate compiler */
	other = -1;

	/* these are the default data columns */
	numcol = 1;
	rowcol = 2;
	colcol = 3;

	for(i = 1; i < argc; i++) {		/* extract new values from command line */
		if ((gotit = find("row", argv[i])) != NULL) {
			rowcol = (int)(evaluate(gotit) + .5);
			continue;
		}
		if ((gotit = find("col", argv[i])) != NULL) {
			colcol = (int)(evaluate(gotit) + .5);
			continue;
		}
		if(keyword("echo",argv[i])){
			echo_flag=1;
			continue;
		}
		if(keyword("help",argv[i])){
			show_options();
			exit(0);
		}
		if ((gotit = find("num", argv[i])) != NULL) {
			numcol = (int)(evaluate(gotit) + .5);
			mode=STATE_NUMBER;
			continue;
		}
		if(fin != stdin)
			error(1,"file already open");
		fin=fopen(argv[i],"r");
		if(fin==NULL){
			fprintf(stderr,"%s: can't open '%s'\n",progname,argv[i]);
			exit(1);
		}
	}

	while(fgets(buf,BIG_BUF,fin)){
		if((numcol==1) && !isspace(buf[0])) /* skip phot or coo headers */
			continue;
		row=(int)(get_col(buf,rowcol)+0.5);
		col=(int)(get_col(buf,colcol)+0.5);
		if(echo_flag)
			puts(buf);
		if(numcol)
			other=(int)(get_col(buf,numcol)+0.5);
		do_mark(row,col,other,mode);
	}
	exit(0);
}

static void show_options()
{
	printf("usage: marks [filename] [num=] [row=] [col=] [echo] [help]\n");
}

	/* all of the following should only be included if the
	   XWINDOWS flag is set */

#ifdef XWINDOWS

/*	
	causes the crosshair to appear in all windows. There is no good way to make
	sure that all windows receive the signal SHOW_CROSSHAIR; 
	all the routine does
	now is set the window state to SHOW_CROSSHAIR, wait for a few seconds, 
	and then re-set the window_state to NORMAL.  
	I hope it works out in practice..
	         - MWR 4/8/92

*/

#define UNAPTIME     50000		/* in microseconds ! */

static Display *display;
static Atom atom_state, actual;
static int data[PROP_NITEMS];
static struct s_prop prop;


	/* returns 0 if all goes well */

static int
do_mark(row, col,other,mode)
int row, col,other,mode;
{
	int i;
	static int flag = 0;

	if (flag == 1)
		return(1);

	if ((display = XOpenDisplay("")) == NULL) {
		flag = 1;
		fprintf(stderr,"%s: you must be running X-windows",progname);
		return(1);
	}
	atom_state = XInternAtom(display, ATOM_STATE, False);
	XGetWindowProperty(display, DefaultRootWindow(display), atom_state,
			(long) 0, (long) PROP_NITEMS, False, XA_INTEGER, &actual,
			&(prop.format), &(prop.nitems), &(prop.bytes), 
#if XGETUNSIGNED == 1
			(unsigned char **) &(prop.data));
#else
			(char **) &(prop.data));
#endif
	for (i = 0; i < PROP_NITEMS; i++)
		data[i] = prop.data[i];

	data[1] = mode;
	data[2] = row;
	data[3] = col;
	data[4] = other;

	signal(SIGINT, sig_trap);
	signal(SIGQUIT, sig_trap);
	signal(SIGTERM, sig_trap);

	XChangeProperty(display, DefaultRootWindow(display), atom_state,
			XA_INTEGER, PROP_FORMAT, PropModeReplace, 
			(unsigned char *) data, PROP_NITEMS);
	XFlush(display);

	vista_usleep(UNAPTIME);

	data[1] = STATE_NORMAL;
	for (i = 2; i < PROP_NITEMS; i++)
		data[i] = 0;
	XChangeProperty(display, DefaultRootWindow(display), atom_state,
			XA_INTEGER, PROP_FORMAT, PropModeReplace, 
			(unsigned char *) data, PROP_NITEMS);

	XCloseDisplay(display);

	return(0);
}

	/* change the property back to NORMAL so that image windows don't 
	   wait forever for ackowledgment. */

static void
sig_trap(x)
int x;
{
	int i;

	XGetWindowProperty(display, DefaultRootWindow(display), atom_state,
			(long) 0, (long) PROP_NITEMS, False, XA_INTEGER, &actual,
			&(prop.format), &(prop.nitems), &(prop.bytes), 
#if XGETUNSIGNED == 1
			(unsigned char **) &(prop.data));
#else
			(char **) &(prop.data));
#endif

	for (i = 0; i < PROP_NITEMS; i++)
		data[i] = prop.data[i];
	data[1] = STATE_NORMAL;

	XChangeProperty(display, DefaultRootWindow(display), atom_state,
			XA_INTEGER, PROP_FORMAT, PropModeReplace, 
			(unsigned char *) data, PROP_NITEMS);

	XCloseDisplay(display);
	exit(0);
}

#endif 		/* XWINDOWS */

