/*
 * di_timer.c
 */

#ifdef  X11_DISP

#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "corewar.h"
#include "cwdisp.h"

#define  SEC_USEC  1000000

static int  timedelay;
static struct timeval  next_interrupt;

/* Set up SIGALRM signals to arrive freq times per second. */
void  di_set_timer(float freq)  {
	float  delay = 1.0 / freq;

	timedelay = (int)(delay * (float)SEC_USEC);
	gettimeofday(&next_interrupt, NULL);
	next_interrupt.tv_usec += timedelay;
}


void  di_unset_timer()  {
}


int  di_timer_wait(Display *dpy)  {
	int  dneeded, waited = TRUE;
	struct timeval  cur_tv;

	gettimeofday(&cur_tv, NULL);
	dneeded = (next_interrupt.tv_usec - cur_tv.tv_usec) +
		((next_interrupt.tv_sec - cur_tv.tv_sec) * SEC_USEC);
	if (dneeded > 0)  {
		XFlush(dpy);
		gettimeofday(&cur_tv, NULL);
		dneeded = (next_interrupt.tv_usec - cur_tv.tv_usec) +
			((next_interrupt.tv_sec - cur_tv.tv_sec) * SEC_USEC);
		if (dneeded > 0)  {
			fd_set  rdfds;
			int  fd = ConnectionNumber(dpy);

			FD_ZERO(&rdfds);
			FD_SET(fd, &rdfds);
			timerclear(&cur_tv);
			cur_tv.tv_usec = dneeded % SEC_USEC;
			cur_tv.tv_sec = dneeded / SEC_USEC;
			waited = select(fd+1, rdfds, NULL, NULL, cur_tv);
			if (waited == 0)
				waited = TRUE;
			else
				waited = FALSE;
		}
	}
	if (waited && ((next_interrupt.tv_usec += timedelay) > SEC_USEC))  {
		++next_interrupt.tv_sec;
		next_interrupt.tv_usec -= SEC_USEC;
	}
	return(waited);
}


#endif  /* X11_DISP */
