
/* This is a program to show how mouse events can be handled by programs
   running under an xterm window.

		-Sam Lantinga		5/11/94
*/

#include <stdio.h>
#include "vtmouse.h"

#undef MAIN
#ifdef MAIN
void event_loop()
{
	int c, event_flag;
	struct event X_event;

	while ( (c=event_getc(&X_event)) != EOF ) {
		if ( X_event.happening ) {
			printf("\r\n************\r\n");
			printf("Mouse Event: 0x%x\r\n", X_event.button_state);
			printf("\tX coordinate: %d\r\n", X_event.x);
			printf("\tY coordinate: %d\r\n", X_event.y);
			/* One example of getting the mouse state */
			printf("\tX Event: ");
			switch(X_event.button_state&BUTTON_MASK) {
				case RELEASE:	printf("Button was released!\r\n");
									break;
				default:			printf("Button %d was pressed!\r\n", 
											(X_event.button_state&BUTTON_MASK)+1);
									break;
			}
			/* Another example of getting the mouse state */
			printf("\tMouse %s buttons <%c|%c|%c>\r\n",
				(BUTTON_ISSET(X_event, RELEASE) ? "released" : "pressed"),
				(BUTTON_ISSET(X_event, BUTTON_1) ? 'X' : ' '),
				(BUTTON_ISSET(X_event, BUTTON_2) ? 'X' : ' '),
				(BUTTON_ISSET(X_event, BUTTON_3) ? 'X' : ' '));
			printf("************\r\n");
		} else {
			if ( c == 'Q' )
				return;
			else  {
				putc(c, stdout);
				if ( c == '\r' )
					putc('\n', stdout);
			}
		}
	}
}

int main(int argc, char *argv[])
{
	if ( event_init(stdin, stdout) < 0 ) {
		printf("Not running under an xterm.\n");
		exit(2);
	}
	system("stty -echo raw");

	event_loop();

	system("stty -raw echo");
	event_quit();

	exit(0);
}
#endif

/* I/O streams default to stdin and stdout. */
FILE *xt_input=stdin, *xt_output=stdout;
static int have_xterm=0;
static int set_title=0;

int event_init(input, output, titlebar)
FILE *input, *output;
char *titlebar;
{
	char *termtype;

	/* A program can assume that input is unbuffered after this routine */
	setbuf(input, NULL);
	xt_input=input;
	xt_output=output;

	/* Check for xterm terminal type */
	if ( (termtype=(char *)getenv("TERM")) && strcmp(termtype, "xterm") == 0 ) {
		fprintf(xt_output, "\033[?1000h");
		fflush(xt_output);
		have_xterm=1;
		if ( titlebar ) {
			fprintf(xt_output, "\033]0;%s\07", titlebar);
			set_title=1;
			fflush(xt_output);
		}
	} else {
		return(-1);
	}
	return(0);
}

int event_getc(X_event)
struct event *X_event;
{
	int c, done=0;
	char *sequence="\033[M\0\0\0", *next=sequence;

	X_event->happening=0;

	if ( have_xterm ) {
		while ( *next ) {
			if ( (c=getc(xt_input)) == EOF )
				return(EOF);
			if ( c == *next )
				++next;
			else {
				*next=(char)c;
				for ( *(next+1)='\0'; (next > sequence); --next )
					ungetc(*next, xt_input);
				return(*sequence);
			}
		}
		/* An event is being sent! */
		X_event->happening=1;
		for ( c=0; c<3; ++c ) {
			if ( (*(next++)=getc(xt_input)) == EOF )
				return(EOF);
		}
		X_event->button_state=(*(sequence+3)-' ');
		X_event->x=(*(sequence+4)-' ');
		X_event->y=(*(sequence+5)-' ');
		*(sequence+3)='\0';	/* Reset the buffer with a null char */
	} else
		return(getc(xt_input));
	return(0);
}

void event_quit()
{
	if ( have_xterm ) {
		fprintf(xt_output, "\033[?1000l");
		fflush(xt_output);
		if ( set_title ) {
			fprintf(xt_output, "\033]0;%s\07", "xterm");
			fflush(xt_output);
		}
	}
}

