/*
 * vwatch.c (monitor the power status of the Veridata EL-486S/25e notebook)
 * Time-stamp: <29 Mar 94 (23:31) by pive@ruca.ua.ac.be>
 */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

#include "veridata.h"

void inline outb_p(char value, unsigned short port)
{
__asm__ __volatile__ ("outb %%al,%%dx"
                ::"a" ((char) value),"d" ((unsigned short) port));
        SLOW_DOWN_IO;
}

unsigned int inline inb_p(unsigned short port)
{
        unsigned int _v;
__asm__ __volatile__ ("inb %%dx,%%al"
                :"=a" (_v):"d" ((unsigned short) port),"0" (0));
        SLOW_DOWN_IO;
        return _v;
}

void signal_exit_handler()
{
  exit(0);
}
   
main(int argc, char *argv[])
{
  unsigned int status,
               level1_cnt, /* beep in level1 if this becomes zero */
               led_on;     /* true if Bat. Low led is on */
  int pid; /* the process id */

  if (iopl(3)) {
    fprintf(stderr,"%s: iopl failed (must be root!)\n",argv[0]);
    exit(1);
  }

  /* I should check the computer */

  pid = fork();
  if (pid)
    exit(0);

  printf("%s: monitoring the power status ",argv[0]);
  printf("of the Veridata EL-486S/25e notebook\n");
  
  signal(SIGINT,signal_exit_handler);
  signal(SIGHUP,signal_exit_handler);
  signal(SIGTERM,signal_exit_handler);
 
  /* make sure we are in a known state */

  status=inb_p(VERIDATA_PORT) & SAFETY_MASK | BAT_LOW_OFF;
  outb_p(status,VERIDATA_PORT);
  led_on=FALSE;

  level1_cnt=0;
  
  while (TRUE) {
    status=inb_p(VERIDATA_PORT);
    switch (status & POWER_MASK) {
    case POWER_OK:
      if (led_on) {
	outb_p(status | BAT_LOW_OFF & SAFETY_MASK,VERIDATA_PORT);
	led_on=FALSE;
      }
      break;
    case POWER_LVL1:
      if (level1_cnt == 0) {
	level1_cnt=4; /* beep each 5 times */
	fprintf(stderr,"");
      } else
	level1_cnt --;
      if (led_on) {
	outb_p(status | BAT_LOW_OFF & SAFETY_MASK,VERIDATA_PORT);
	led_on=FALSE;
      } else {
	led_on=TRUE;
	outb_p(status & ~BAT_LOW_OFF & SAFETY_MASK,VERIDATA_PORT);
      }
      break;
    case POWER_LVL2:
      fprintf(stderr,"");
      if (!led_on) {
	led_on=TRUE;
	outb_p(status & ~BAT_LOW_OFF & SAFETY_MASK,VERIDATA_PORT);
      }
      break;
    }
    sleep(1);
  }
}
