/*
 * apmd.c
 */

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include "asmi.h"

void signal_exit_handler()
{
	int	retval;

	retval = asmi(APM_INTERFACE_DISCONNECT, 0, 0, 0, 0, 0);
	if (retval) {
		printf("interface disconnect: %s\n", apm_error(retval));
		exit(1);
	}
	exit(0);
}

void detach()
{
	int	pid;
	
	pid = fork();
	if (pid)
		exit(0);
}

int main(int argc, char *argv)
{
	int	retval;
	unsigned int	vers, check, flags;
	unsigned int	event;
	
	if (iopl (3) < 0) {
		perror ("iopl");
		return 1;
	}

	retval = asmi(APM_INSTALLATION_CHECK, 0, 0, &vers, &check, &flags);
	if (retval) {
		printf ("APM install check: %s\n", apm_error (retval));
		exit(1);
	}

	printf ("APM install check: v%02x.%02x%c%c flags %x [",
	      vers >> 8, vers & 0xff, check >> 8, check & 0xff, flags);
	/* now print flags */
	if (flags & 1) printf (" 16");
	if (flags & 2) printf (" 32");
	printf (" idle=%s bios-pm-%s ]\n",
		(flags & 4) ? "slow" : "stop",
		(flags & 8) ? "disabled" : "enabled");

	retval = asmi(APM_INTERFACE_CONNECT, 0, 0, 0, 0, 0);
	if (retval) {
		printf ("interface connect: %s\n", apm_error (retval));
		exit(1);
	}

	detach();

	signal(SIGINT, signal_exit_handler);
	signal(SIGHUP, signal_exit_handler);
	signal(SIGTERM, signal_exit_handler); 

	while (1) {
		fflush (stdout);
		sleep (1);
		retval = asmi(APM_GET_PM_EVENT, 0, 0, 0, &event, 0);
		if (retval == APM_NO_EVENT_PENDING)
			continue;
		if (retval == APM_INTERFACE_NOT_CONNECTED) {
			retval = asmi(APM_INTERFACE_CONNECT, 0, 0, 0, 0, 0);
			if (retval) {
				printf ("interface connect: %s\n",
					apm_error (retval));
				exit(1);
			}
			continue;
		}
		if (retval) {
			printf ("PM event fetch: %s\n", apm_error (retval));
			exit(1);
		}
#if 0
		printf ("PM event type %x\n", event);
#endif
		switch (event) {
		case APM_EVENT_STANDBY_REQUEST:
			retval = asmi(APM_SET_POWER_STATE, 1, 1, 0, 0, 0);
			if (retval) {
				printf("set system standby: %s\n",
				       apm_error(retval));
				exit(1);
			}
		case APM_EVENT_SUSPEND_REQUEST:
			retval = asmi(APM_SET_POWER_STATE, 1, 2, 0, 0, 0);
			if (retval) {
				printf("set system suspend: %s\n",
				       apm_error(retval));
				exit(1);
			}
		case APM_EVENT_NORMAL_RESUME:
		case APM_EVENT_CRITICAL_RESUME:
			system("/etc/clock -s");
			break;
		case APM_EVENT_BATTERY_LOW:
			printf("\007\007\007BATTERY LOW\007\007\007\n");
			break;
		}
	}
}
	

