/*

   YAWMPPP - PPP dock app/helper for WindowMaker
   Copyright (C) 2000,2001:

   Author:  Felipe Bergo     (bergo@seul.org)

   based on the wmppp application by

            Martijn Pieterse (pieterse@xs4all.nl)
            Antoine Nulle    (warp@xs4all.nl)

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

   $Id: yawmppp.c,v 1.1.1.1 2001/02/22 07:16:01 bergo Exp $
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <signal.h>

#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/types.h>

#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>

#include "wmgeneral.h"
#include "misc.h"
#include "isprc.h"
#include "ycommon.h"

#include "dockxpm.xpm"
#include "yawmppp.h"

/* external vars */

extern char **environ;

/* global variables */

long starttime;

char *ProgName;
char *active_interface = "ppp0";
int TimerDivisor = 60;
int updaterate = 5;

int dock_mask_width = 64;
int dock_mask_height = 64;
char dock_mask_bits[64 * 64];

int current_isp = 0;
int num_isps = 0;

int got_sched=0;
int caution=1;

struct YAWMPPP_ISP_INFO IspData[MAX_ISPS];

/* log data */
struct {
  time_t start;
  time_t end;
  int    status; /* 0=ok 1=error 2=crash */
  char   longname[128];
  char   shortname[16];
  char   phone[32];
  char   user[32];
} logconn;

/* PPP variables */

#define 	PPP_UNIT		0
int ppp_h = -1;
int ppp_open = 0;

#define		PPP_STATS_HIS	54

int pixels_per_byte;

int ppp_history[PPP_STATS_HIS + 1][2];

/* main */

int
main (int argc, char *argv[])
{

    int i;

    /* Parse Command Line */

    ProgName = argv[0];
    if (strlen (ProgName) >= 5)
	ProgName += (strlen (ProgName) - 5);

    for (i = 1; i < argc; i++)
      {
	  char *arg = argv[i];

	  if (*arg == '-')
	    {
		switch (arg[1])
		  {
		  case 'c':
		    caution=1;
		    break;
		  case 'd':
		      if (strcmp (arg + 1, "display"))
			{
			    usage ();
			    exit (1);
			}
		      break;
		  case 'g':
		      if (strcmp (arg + 1, "geometry"))
			{
			    usage ();
			    exit (1);
			}
		      break;
		  case 'i':
		      if (!argv[i + 1])
			{
			    usage ();
			    exit (1);
			}
		      if (strncmp (argv[i + 1], "ppp", 3))
			{
			    usage ();
			    exit (1);
			}
		      active_interface = argv[i + 1];
		      i++;
		      break;
		  case 'p':
		    caution=2;
		    break;
		  case 't':
		      TimerDivisor = 1;
		      break;
		  case 'u':
		      i++;
		      if (!argv[i])
			{
			    usage ();
			    exit (1);
			}
		      updaterate = atoi (argv[i]);
		      if (updaterate < 1 || updaterate > 10)
			{
			    usage ();
			    exit (1);
			}
		      break;
		  case 'v':
		      printversion ();
		      exit (0);
		      break;
		  case 'z':
		    printf("Caution level: %d\n",caution);
		    break;
		  default:
		      usage ();
		      exit (0);
		      break;
		  }
	    }
      }

    for (i = 0; i < MAX_ISPS; i++)
      memset(&IspData[i],0,sizeof(struct YAWMPPP_ISP_INFO));

    make_config_dir();
    signal(SIGUSR1,sigusr_handler);
    signal(SIGHUP,sigusr_handler);
    signal(SIGINT,sigusr_handler);
    signal(SIGTERM,sigusr_handler);

    write_pid_file();
    clean_guards();

    yawmppp_routine (argc, argv);

    return 0;
}

void
yawmppp_routine (int argc, char **argv)
{
    int i, j;

    int but_stat;

    long currenttime;
    long lasttime;
    long waittime;
    long ppptime;
    int hour, minute;
    long timetolog;

    long ppp_send, ppp_sl = -1;
    long ppp_recv, ppp_rl = -1;
    long ppp_sbytes, ppp_rbytes;
    long ppp_osbytes, ppp_orbytes;

    struct stat st;

    pid_t stop_child = 0;
    pid_t start_child = 0;
    int status;

    int isonline = 0;

    XEvent Event;

    int speed_ind = 10;

    /* Initialize some stuff */

    get_statistics (active_interface, &ppp_rl, &ppp_sl,
		    &ppp_orbytes, &ppp_osbytes);
    if (caution>0)
      close_ppp();

    grab_isp_info(1);

    /* Open the display */

    createXBMfromXPM (dock_mask_bits, dockxpm_xpm,
		      dock_mask_width, dock_mask_height);

    openXwindow (argc, argv, dockxpm_xpm, dock_mask_bits,
		 dock_mask_width, dock_mask_height);

    /* V Button */
    AddMouseRegion (0, 35, 48, 46, 58);
    /* x Button */
    AddMouseRegion (1, 47, 48, 58, 58);

    /* < Button */
    AddMouseRegion (2, 5, 48, 16, 58);
    /* > Button */
    AddMouseRegion (3, 17, 48, 28, 58);
    /* ISP display */
    AddMouseRegion (4, 5, 6, 59, 43);

    starttime = 0;
    currenttime = time (0);
    ppptime = 0;
    but_stat = -1;
    waittime = 0;
    timetolog=0;

    /* 888k8 on bottom */
    copyXPMArea (ERR_SRC_X+28, ERR_SRC_Y+9, 25, 8, ERR_DEST_X, ERR_DEST_Y);

    DrawISPName ();

    while (1)
      {
	  lasttime = currenttime;
	  currenttime = time (0);

	  /* Check if any child has left the playground */
	  i = waitpid (0, &status, WNOHANG);
	  if (i == stop_child && stop_child != 0)
	    {

		starttime = 0;
		SetOffLED (LED_PPP_POWER);
		SetOffLED (LED_PPP_RX);
		SetOffLED (LED_PPP_TX);
		/* 888k8 on bottom */
		copyXPMArea (ERR_SRC_X+28, ERR_SRC_Y+9, 25, 8,
			     ERR_DEST_X, ERR_DEST_Y);
		RedrawWindow ();

		stop_child = 0;
	    }
	  if (i == start_child && start_child != 0)
	    {
		if (WIFEXITED (status))
		  {
		      if (WEXITSTATUS (status) == 10)
			{

			    starttime = 0;
			    /* 88k8 on bottom */
			    copyXPMArea (ERR_SRC_X+28, ERR_SRC_Y+9, 25, 8,
					 ERR_DEST_X, ERR_DEST_Y);
			    SetOffLED (LED_PPP_POWER);
			    DrawTime (0, 1);
			    RedrawWindow ();
			}
		      start_child = 0;
		  }
	    }

	  /* On-line detectie! 1x per second */

	  if (currenttime != lasttime)
	    {
		i = 0;

		if (stillonline (active_interface))
		  {
		      i = 1;
		      if (!starttime)
			{
			    starttime = currenttime;

			    if (stat (STAMP_FILE, &st) == 0)
				starttime = st.st_mtime;

			    SetOnLED (LED_PPP_POWER);
			    waittime = 0;

			    /* 88k8 on bottom */
			    copyXPMArea (ERR_SRC_X+28, ERR_SRC_Y+9, 25, 8,
					 ERR_DEST_X, ERR_DEST_Y);

			    if (IspData[current_isp].SpeedAction)
				DrawSpeedInd (IspData[current_isp].SpeedAction);

			    speed_ind = currenttime + 10;

			    RedrawWindow ();
			}
		  }
		if (!i && starttime)
		  {
		      starttime = 0;
		      SetErrLED (LED_PPP_POWER);
		      logconn.status=1;

		      /* Error */
		      copyXPMArea (ERR_SRC_X, ERR_SRC_Y+9, 25, 8,
				   ERR_DEST_X, ERR_DEST_Y);

		      if (IspData[current_isp].IfDownAction)
			  execCommand (IspData[current_isp].IfDownAction);

		      RedrawWindow ();
		  }
	    }

	  if (waittime && waittime <= currenttime)
	    {
		SetOffLED (LED_PPP_POWER);
		RedrawWindow ();
		waittime = 0;
	    }

	  if ((starttime)&&(!isonline)) {
	    isonline=1;

	    logconn.start=time(NULL);
	    logconn.status=0;
	    strcpy(logconn.longname,IspData[current_isp].LongName);
	    strcpy(logconn.shortname,IspData[current_isp].ShortName);
	    strcpy(logconn.user,IspData[current_isp].User);
	    strcpy(logconn.phone,IspData[current_isp].Phone);

	    if (!strlen(logconn.shortname))
	      strcpy(logconn.shortname,"empty");
	    if (!strlen(logconn.longname))
	      strcpy(logconn.longname,"empty");
	    if (!strlen(logconn.user))
	      strcpy(logconn.user,"empty");
	    if (!strlen(logconn.phone))
	      strcpy(logconn.phone,"empty");

	    make_guards();
	  }
	  if ((!starttime)&&(isonline)) {
	    isonline=0;
	    logconn.end=time(NULL);
	    write_log();
	    if (got_sched)
	      make_delayed_update();
	    if (caution>0)
	      close_ppp();
	  }

	  /* If we are on-line. Print the time we are */
	  if (starttime)
	    {
		i = currenttime - starttime;

		i /= TimerDivisor;

		if (TimerDivisor == 1)
		    if (i > 59 * 60 + 59)
			i /= 60;

		minute = i % 60;
		hour = (i / 60) % 100;
		i = hour * 100 + minute;

		DrawTime (i, currenttime % 2);
		/* We are online, so we can check for send/recv packets */

		get_statistics (active_interface, &ppp_recv, &ppp_send,
				&ppp_rbytes, &ppp_sbytes);
		if (caution>1)
		  close_ppp();

		if (ppp_send != ppp_sl)
		    SetOnLED (LED_PPP_TX);
		else
		    SetOffLED (LED_PPP_TX);

		if (ppp_recv != ppp_rl)
		    SetOnLED (LED_PPP_RX);
		else
		    SetOffLED (LED_PPP_RX);

		ppp_sl = ppp_send;
		ppp_rl = ppp_recv;

		/* Every five seconds we check to load on the line */

		if (currenttime - timetolog >= 0) {
		  timetolog=currenttime + 60;
		  make_guards();
		}

		if ((currenttime - ppptime >= 0) || (ppptime == 0))
		  {

		      ppptime = currenttime + updaterate;

		      ppp_history[PPP_STATS_HIS][0] = ppp_rbytes - ppp_orbytes;
		      ppp_history[PPP_STATS_HIS][1] = ppp_sbytes - ppp_osbytes;

		      ppp_orbytes = ppp_rbytes;
		      ppp_osbytes = ppp_sbytes;

		      DrawStats (54, 17, 5, 32);

		      for (j = 1; j < 55; j++)
			{
			    ppp_history[j - 1][0] = ppp_history[j][0];
			    ppp_history[j - 1][1] = ppp_history[j][1];
			}
		      if (currenttime > speed_ind)
			{
			    DrawLoadInd ((ppp_history[54][0] + ppp_history[54][1]) / updaterate);
			}
		  }

		RedrawWindow ();
	    }


	  while (XPending (display))
	    {
		XNextEvent (display, &Event);
		switch (Event.type)
		  {
		  case Expose:
		      RedrawWindow ();
		      break;
		  case DestroyNotify:
		      XCloseDisplay (display);
		      while (start_child | stop_child)
			{
			    i = waitpid (0, &status, WNOHANG);
			    if (i == stop_child)
				stop_child = 0;
			    if (i == start_child)
				start_child = 0;
			    usleep (50000l);
			}
		      exit (0);
		      break;
		  case ButtonPress:
		      i = CheckMouseRegion (Event.xbutton.x, Event.xbutton.y);
		      switch (i)
			{
			case 0:
			    ButtonDown (BUT_V);
			    break;
			case 1:
			    ButtonDown (BUT_X);
			    break;
			case 2:
			    ButtonDown (BUT_REW);
			    break;
			case 3:
			    ButtonDown (BUT_FF);
			    break;
			}
		      but_stat = i;

		      RedrawWindow ();
		      break;
		  case ButtonRelease:
		      i = CheckMouseRegion (Event.xbutton.x, Event.xbutton.y);
		      // Button but_stat omhoogdoen!
		      switch (but_stat)
			{
			case 0:
			    ButtonUp (BUT_V);
			    break;
			case 1:
			    ButtonUp (BUT_X);
			    break;
			case 2:
			    ButtonUp (BUT_REW);
			    break;
			case 3:
			    ButtonUp (BUT_FF);
			    break;
			}

		      if (i == but_stat && but_stat >= 0)
			{
			    switch (i)
			      {
			      case 0:
				  if (!starttime)
				    {
				      /* 888k8 */
				      copyXPMArea (ERR_SRC_X+28, ERR_SRC_Y+9,
						   25, 8,
						   ERR_DEST_X, ERR_DEST_Y);
					DrawTime (0, 1);
					start_child = execCommand (IspData[current_isp].StartAction);
					SetWaitLED (LED_PPP_POWER);
					waittime = ORANGE_LED_TIMEOUT + currenttime;
				    }

				  break;
			      case 1:
				  if (stop_child == 0)
				    {
					stop_child = execCommand (IspData[current_isp].StopAction);
				    }
				  break;
			      case 2:
				  if (!starttime)
				    {
					current_isp--;
					if (current_isp < 0)
					    current_isp = num_isps - 1;
					if (current_isp < 0)
					  current_isp=0;
					DrawISPName ();
				    }
				  break;
			      case 3:
				  if (!starttime)
				    {
					current_isp++;
					if (current_isp == num_isps)
					    current_isp = 0;
					DrawISPName ();
				    }
				  break;
			      case 4:
				if (Event.xbutton.button==Button1)
				  run_pref_app();
				else
				  run_log_app();
				break;
			      }
			}
		      RedrawWindow ();

		      but_stat = -1;
		      break;
		  default:
		      break;
		  }
	    }
	  usleep (50000L);
      }
}

/* DrawTime */

void
DrawTime (int i, int j)
{

    int k = 1000;

    copyXPMArea (TIMER_SZE_X * ((i / k) % 10) + 1, TIMER_SRC_Y,
		 5, 7,
		 TIMER_DES_X + 6 * 0, TIMER_DES_Y);
    k = k / 10;
    copyXPMArea (TIMER_SZE_X * ((i / k) % 10) + 1, TIMER_SRC_Y,
		 5, 7,
		 TIMER_DES_X + 6 * 1, TIMER_DES_Y);
    k = k / 10;

    /* colon */
    if (j)
	copyXPMArea (62, TIMER_SRC_Y,
		     1, 7,
		     TIMER_DES_X + 6 * 2 + 1, TIMER_DES_Y);
    else
	copyXPMArea (63, TIMER_SRC_Y,
		     1, 7,
		     TIMER_DES_X + 6 * 2 + 1, TIMER_DES_Y);

    copyXPMArea (TIMER_SZE_X * ((i / k) % 10) + 1, TIMER_SRC_Y,
		 5, 7,
		 TIMER_DES_X + 6 * 2 + 4, TIMER_DES_Y);
    k = k / 10;
    copyXPMArea (TIMER_SZE_X * ((i / k) % 10) + 1, TIMER_SRC_Y,
		 5, 7,
		 TIMER_DES_X + 6 * 3 + 4, TIMER_DES_Y);
}

void
DrawStats (int num, int size, int x_left, int y_bottom)
{

    int pixels_per_byte;
    int j, k;

    pixels_per_byte = size;
    for (j = 0; j < num; j++)
      if ((ppp_history[j][0]+ppp_history[j][1]) > pixels_per_byte)
	pixels_per_byte = ppp_history[j][0] + ppp_history[j][1];

    pixels_per_byte /= size;

    for (k = 0; k < num; k++)
      for (j = 0; j < size; j++)
	{
	  if (j < (ppp_history[k][0] / pixels_per_byte))
	    copyXPMArea (58 + 2, 92, 1, 1, k + x_left, y_bottom - j);
	  else if (j < (ppp_history[k][0] + ppp_history[k][1]) / pixels_per_byte)
	    copyXPMArea (58 + 1, 92, 1, 1, k + x_left, y_bottom - j);
	  else
	    copyXPMArea (58 + 0, 92, 1, 1, k + x_left, y_bottom - j);
	}
}

void
PrintLittle (int i, int *k)
{

    switch (i)
      {
      case -1:
	  *k -= 5;
	  copyXPMArea (12 * 5, ERR_SRC_Y, 4, 8, *k, ERR_DEST_Y);
	  break;
      case 0:
	  *k -= 5;
	  copyXPMArea (45, ERR_SRC_Y, 5, 8, *k, ERR_DEST_Y);
	  break;
      default:
	  *k -= 5;
	  copyXPMArea (i * 5 - 5, ERR_SRC_Y, 5, 8, *k, ERR_DEST_Y);
	  break;
      }
}

void
DrawSpeedInd (char *speed_action)
{

    int linespeed, i, k;
    FILE *fp;
    char *p;
    char temp[128];

    fp = popen (speed_action, "r");

    if (fp)
      {
	  linespeed = 0;

	  while (fgets (temp, 128, fp))
	      ;

	  pclose (fp);

	  if ((p = strstr (temp, "CONNECT")))
	    {
		linespeed = atoi (p + 8);
	    }

	  k = ERR_DEST_X+25;

	  i = (linespeed % 1000) / 100;
	  linespeed /= 1000;
	  PrintLittle (i, &k);

	  k -= 5;
	  copyXPMArea (ERR_SRC_X+50, ERR_SRC_Y, 5, 8, k, ERR_DEST_Y);

	  do
	    {
		PrintLittle (linespeed % 10, &k);
		linespeed /= 10;
	    }
	  while (linespeed);
      }
}

/* DrawLoadInd */

void
DrawLoadInd (int speed)
{

    int i, k;

    k = ERR_DEST_X+25;
    for (i = 0; i < 5; i++)
	PrintLittle (-1, &k);

    k = ERR_DEST_X+25;

    do
      {
	  PrintLittle (speed % 10, &k);
	  speed /= 10;
      }
    while (speed);
}

/* usage */

void
usage (void)
{
    fprintf (stderr,
	     "\nyawmppp - Yet Another Window Maker PPP dock applet\n\n");
    fprintf (stderr,
	     "version %s\n\n",VERSION);
    fprintf (stderr, "usage:\n");
    fprintf (stderr, "-h                   this help screen\n");
    fprintf (stderr, "-i <device>          (ppp0, ppp1, etc)\n");
    fprintf (stderr, "-t                   set the on-line timer to MM:SS instead of HH:MM\n");
    fprintf (stderr, "-u <update rate>     (1..10), default 5 seconds\n");
    fprintf (stderr, "-v                   print the version number\n");
    fprintf (stderr, "-paranoid            be paranoid about open sockets\n");
    fprintf (stderr, "\n");
}

/* printversion */

void
printversion (void)
{
    fprintf (stderr, "%s\n", VERSION);
}

/* SetOnLED */

void
SetOnLED (int led)
{
    switch (led)
      {
      case LED_PPP_POWER:
	  copyXPMArea (LED_ON_X, LED_ON_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
	  break;
      case LED_PPP_RX:
	  copyXPMArea (ARR_DN_X, ARR_DN_Y+ARR_ACTV, ARR_W, ARR_H, LED_RCV_X, LED_RCV_Y);
	  break;
      case LED_PPP_TX:
	  copyXPMArea (ARR_UP_X, ARR_UP_Y+ARR_ACTV, ARR_W, ARR_H, LED_SND_X, LED_SND_Y);
	  break;
      }
}

/* SetOffLED */

void
SetOffLED (int led)
{

    switch (led)
      {
      case LED_PPP_POWER:
	  copyXPMArea (LED_OFF_X, LED_OFF_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
	  break;
      case LED_PPP_RX:
	  copyXPMArea (ARR_DN_X, ARR_DN_Y , ARR_W, ARR_H, LED_RCV_X, LED_RCV_Y);
	  break;
      case LED_PPP_TX:
	  copyXPMArea (ARR_UP_X, ARR_UP_Y, ARR_W, ARR_H, LED_SND_X, LED_SND_Y);
	  break;

      }
}

/* SetErrELD */

void
SetErrLED (int led)
{

    switch (led)
      {
      case LED_PPP_POWER:
	  copyXPMArea (LED_ERR_X, LED_ERR_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
	  break;
      }
}

/* SetWaitLED */

void
SetWaitLED (int led)
{

    switch (led)
      {
      case LED_PPP_POWER:
	  copyXPMArea (LED_WTE_X, LED_WTE_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
	  break;
      }
}

/* Button Up */

void
ButtonUp (int button)
{

    switch (button)
      {
      case BUT_V:
	  copyXPMArea (BUT_V_SRC_X+BUT_UP_INC, BUT_V_SRC_Y,
		       12, 11,
		       BUT_V_X, BUT_V_Y);
	  break;
      case BUT_X:
	  copyXPMArea (BUT_X_SRC_X+BUT_UP_INC, BUT_X_SRC_Y,
		       12, 11,
		       BUT_X_X, BUT_X_Y);
	  break;
      case BUT_REW:
	  copyXPMArea (BUT_R_SRC_X+BUT_UP_INC, BUT_R_SRC_Y,
		       12, 11,
		       BUT_R_X, BUT_R_Y);
	  break;
      case BUT_FF:
	  copyXPMArea (BUT_F_SRC_X+BUT_UP_INC, BUT_F_SRC_Y,
		       12, 11,
		       BUT_F_X, BUT_F_Y);
	  break;
      }
}

/* Button Down */

void
ButtonDown (int button)
{

    switch (button)
      {
      case BUT_V:
	  copyXPMArea (BUT_V_SRC_X, BUT_V_SRC_Y,
		       12, 11,
		       BUT_V_X, BUT_V_Y);
	  break;
      case BUT_X:
	  copyXPMArea (BUT_X_SRC_X, BUT_X_SRC_Y,
		       12, 11,
		       BUT_X_X, BUT_X_Y);
	  break;
      case BUT_REW:
	  copyXPMArea (BUT_R_SRC_X, BUT_R_SRC_Y,
		       12, 11,
		       BUT_R_X, BUT_R_Y);
	  break;
      case BUT_FF:
	  copyXPMArea (BUT_F_SRC_X, BUT_F_SRC_Y,
		       12, 11,
		       BUT_F_X, BUT_F_Y);
	  break;
      }
}

void
DrawISPName (void)
{
    int i, s;

    s = strlen (IspData[current_isp].ShortName);
    for (i = 0; i < 5; i++)
      {
	  if (s >= (i + 1))
	      draw_isp_char (i, IspData[current_isp].ShortName[i]);
	  else
	      draw_isp_char (i, ' ');
      }
}

void
draw_isp_char (int pos, char letter)
{
    int sx = 0, sy = 0, ac = 0;

    if ((!ac) && (letter >= 'A') && (letter <= 'Z'))
      {
	  sx = UPPER_ABC_BASE_X;
	  sy = UPPER_ABC_BASE_Y;
	  sy += 8 * ((letter - 'A') / 12);
	  sx += 5 * ((letter - 'A') % 12);
	  ac = 1;
      }
    if ((!ac) && (letter >= 'a') && (letter <= 'z'))
      {
	  sx = LOWER_ABC_BASE_X;
	  sy = LOWER_ABC_BASE_Y;
	  sy += 8 * ((letter - 'a') / 12);
	  sx += 5 * ((letter - 'a') % 12);
	  ac = 1;
      }
    if ((!ac) && (letter >= '0') && (letter <= '9'))
      {
	  sx = DIGIT_BASE_X;
	  sy = DIGIT_BASE_Y;
	  sx += 5 * (letter - '0');
	  ac = 1;
      }
    if (!ac)
      {
	  sx = SPACE_BASE_X;
	  sy = SPACE_BASE_Y;
      }

    copyXPMArea (sx, sy, 4, 7, ISP_BASE_X + 5 * pos, ISP_BASE_Y);
}

void
sigusr_handler(int signum)
{
  if (signum==SIGUSR1) {
    if (!starttime) {
      grab_isp_info(0);
      if (current_isp>=num_isps)
	current_isp=0;
      DrawISPName();
      RedrawWindow();
    } else {
      got_sched=1;
      warn_pref();
    }
  }
  else {
    remove_pid_file();
    exit(0);
  }
}

void
make_delayed_update(void)
{
  grab_isp_info(0);
  if (current_isp>=num_isps)
    current_isp=0;
  DrawISPName();
  RedrawWindow();
  got_sched=0;
}

