/*
 * This file contains the x callbacks for various things.
 *
 * Copyright 1990 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 *
 * Tom Coppeto
 * MIT Network Services
 * 8 August 1990
 *
 *    $Source: /afs/net.mit.edu/tools/src/xport/RCS/callback.c,v $
 *    $Author: tom $
 *    $Locker: paco $
 *    $Log:	callback.c,v $
 * Revision 1.1  90/08/15  01:12:27  tom
 * Initial revision
 * 
 */

#ifndef lint
static char *rcsid = "$Header: /afs/net.mit.edu/tools/src/xport/RCS/callback.c,v 1.1 90/08/15 01:12:27 tom Exp Locker: paco $";
#endif

#include "xport.h"

#include <X11/Xatom.h>
#include <X11/IntrinsicP.h>
#include <X11/CompositeP.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Paned.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Viewport.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/StripChart.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xaw/Dialog.h>
#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/Sme.h>
#include <X11/Xaw/SmeBSB.h>

#include <mit-copyright.h>

extern XtAppContext  app_con;


void 
set_port(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  struct   _port *p;
  Arg       args[3];
  caddr_t   d;
  int       state = 0;
  Dimension width;

  if(protect || (dsp_mode != DISPLAY_STATUS))
    {
      redraw();
      return;
    }

  p = (struct _port *) data;
  XtSetArg(args[0], XtNstate , (XtArgVal) &state);
  XtSetArg(args[1], XtNwidth,  (XtArgVal) &width);
  XtGetValues(w, args, 2);
  ++state;
  vPortAdminStatus.cmp[vPortAdminStatus.ncmp - 1] = p->portnum;
  vPortAdminStatus.cmp[vPortAdminStatus.ncmp - 2] = p->boardnum;
  make_snmp_set(&vPortAdminStatus, &state, INT);  
  if(!(d = make_snmp_query(&vPortAdminStatus)))
    {
      redraw();
      return;
    }
  bcopy(d, &(p->astatus.status), sizeof(p->astatus.status));
  if((p->astatus.status == ADMIN_OFF) && (state == ADMIN_OFF))
    {
      XWarpPointer(XtDisplay(w), XtWindow(w), None, 0, 0, 0, 0, 
		   width+16, 0);		
      explode(w, NULL);
    }
  redraw();
}




void 
restart(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  struct   _port *p;
  Arg       args[3];
  caddr_t   d;
  int       state = DEVICE_RESTART;

  if(protect)
    {
      redraw();
      return;
    }

  
  make_snmp_set(&vDeviceRestart, &state, INT);  
  sleep(1);
  update_status();
  redraw();
}





void
stat_device(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  Widget      popup;
  Widget      form;
  Widget      label;
  Widget      text;
  Widget      box;
  Widget      quit;
  Widget      update;
  Position    x, y;
  Dimension   width, height;
  Cardinal    n;
  Arg         args[10];
  char        *stats;

  stats = do_device_stats();

  /*
   * This will position the upper left hand corner of the popup at the
   * center of the widget which invoked this callback, which will also
   * become the parent of the popup.  I don't deal with the possibility
   * that the popup will be all or partially off the edge of the screen.
   */
  
  n = 0;
  XtSetArg(args[0], XtNwidth,  (XtArgVal) &width);    n++;
  XtSetArg(args[1], XtNheight, (XtArgVal) &height);   n++;
  XtGetValues(w, args, n);
  XtTranslateCoords(w, (Position) (width / 2), (Position) (height / 2),&x, &y);
  
  n = 0;
  XtSetArg(args[n], XtNx, (XtArgVal) x);              n++;
  XtSetArg(args[n], XtNy, (XtArgVal) y);              n++;

  popup = XtCreatePopupShell("statPopup", transientShellWidgetClass, w,
			    args, n);

  form  = XtCreateManagedWidget("popupForm", formWidgetClass, popup, NULL, 0);

  XtSetArg(args[n], XtNlabel, (XtArgVal) sysdesc);    n++;
  label = XtCreateManagedWidget("popupLabel", labelWidgetClass, form, 
				args, n);

  n = 0;
  XtSetArg(args[n], XtNstring, stats);               n++;
  XtSetArg(args[n], XtNfromVert, label);             n++;
  text = XtCreateManagedWidget("statText", asciiTextWidgetClass, form, 
			       args, n);

  n = 0;
  XtSetArg(args[n], XtNfromVert, (XtArgVal) text);   n++;
  box = XtCreateManagedWidget("popupBox", formWidgetClass, form, args, n);

  quit = XtCreateManagedWidget("popupQuit", commandWidgetClass, box, NULL, 0);
  XtAddCallback(quit, XtNcallback, destroy_widget, popup);
/*
  n = 0;
  XtSetArg(args[n], XtNfromHoriz, (XtArgVal) quit);  n++;
  update = XtCreateManagedWidget("popupUpdate", commandWidgetClass, box, 
				 args, n);
  XtAddCallback(quit, XtNcallback, update_port_stats, data); */

  XtPopup(popup, XtGrabNone);
}





void
stat_board(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  Widget      popup;
  Widget      form;
  Widget      label;
  Widget      text;
  Widget      box;
  Widget      quit;
  Widget      update;
  Position    x, y;
  Dimension   width, height;
  Cardinal    n;
  Arg         args[10];
  char        *stats;
  char        line[BUFSIZ];
  int         bn;

  bn = (int) data;
  stats = do_board_stats(bn);

  /*
   * This will position the upper left hand corner of the popup at the
   * center of the widget which invoked this callback, which will also
   * become the parent of the popup.  I don't deal with the possibility
   * that the popup will be all or partially off the edge of the screen.
   */
  
  n = 0;
  XtSetArg(args[0], XtNwidth,  (XtArgVal) &width);    n++;
  XtSetArg(args[1], XtNheight, (XtArgVal) &height);   n++;
  XtGetValues(w, args, n);
  XtTranslateCoords(w, (Position) (width / 2), (Position) (height / 2),&x, &y);
  
  n = 0;
  XtSetArg(args[n], XtNx, (XtArgVal) x);              n++;
  XtSetArg(args[n], XtNy, (XtArgVal) y);              n++;

  popup = XtCreatePopupShell("statPopup", transientShellWidgetClass, w,
			    args, n);

  form  = XtCreateManagedWidget("popupForm", formWidgetClass, popup, NULL, 0);

  sprintf(line, "Board %d (%s)", bn, board[bn-1].name);
  XtSetArg(args[n], XtNlabel, (XtArgVal) line);      n++;
  label = XtCreateManagedWidget("popupLabel", labelWidgetClass, form, 
				args, n);

  n = 0;
  XtSetArg(args[n], XtNstring, stats);               n++;
  XtSetArg(args[n], XtNfromVert, label);             n++;
  text = XtCreateManagedWidget("statText", asciiTextWidgetClass, form, 
			       args, n);

  n = 0;
  XtSetArg(args[n], XtNfromVert, (XtArgVal) text);   n++;
  box = XtCreateManagedWidget("popupBox", formWidgetClass, form, args, n);

  quit = XtCreateManagedWidget("popupQuit", commandWidgetClass, box, NULL, 0);
  XtAddCallback(quit, XtNcallback, destroy_widget, popup);
/*
  n = 0;
  XtSetArg(args[n], XtNfromHoriz, (XtArgVal) quit);  n++;
  update = XtCreateManagedWidget("popupUpdate", commandWidgetClass, box, 
				 args, n);
  XtAddCallback(quit, XtNcallback, update_port_stats, data); */

  XtPopup(popup, XtGrabNone);
}




void
stat_port(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  Widget      popup;
  Widget      form;
  Widget      label;
  Widget      text;
  Widget      box;
  Widget      quit;
  Widget      update;
  Position    x, y;
  Dimension   width, height;
  Cardinal    n;
  Arg         args[10];
  char        *stats;
  char        line[BUFSIZ];
  struct      _port *port;

  stats = do_port_stats(data);
  port = (struct _port *) data;

  /*
   * This will position the upper left hand corner of the popup at the
   * center of the widget which invoked this callback, which will also
   * become the parent of the popup.  I don't deal with the possibility
   * that the popup will be all or partially off the edge of the screen.
   */
  
  n = 0;
  XtSetArg(args[0], XtNwidth,  (XtArgVal) &width);    n++;
  XtSetArg(args[1], XtNheight, (XtArgVal) &height);   n++;
  XtGetValues(w, args, n);
  XtTranslateCoords(w, (Position) (width / 2), (Position) (height / 2),&x, &y);
  
  n = 0;
  XtSetArg(args[n], XtNx, (XtArgVal) x);              n++;
  XtSetArg(args[n], XtNy, (XtArgVal) y);              n++;

  popup = XtCreatePopupShell("statPopup", transientShellWidgetClass, w,
			    args, n);

  form  = XtCreateManagedWidget("popupForm", formWidgetClass, popup, NULL, 0);

  sprintf(line, "Board %d (%s) Port %d", port->boardnum, 
	  board[port->boardnum-1].name, port->portnum);
  XtSetArg(args[n], XtNlabel, (XtArgVal) line);      n++;
  label = XtCreateManagedWidget("popupLabel", labelWidgetClass, form, 
				args, n);

  n = 0;
  XtSetArg(args[n], XtNstring, stats);               n++;
  XtSetArg(args[n], XtNfromVert, label);             n++;
  text = XtCreateManagedWidget("statText", asciiTextWidgetClass, form, 
			       args, n);

  n = 0;
  XtSetArg(args[n], XtNfromVert, (XtArgVal) text);   n++;
  box = XtCreateManagedWidget("popupBox", formWidgetClass, form, args, n);

  quit = XtCreateManagedWidget("popupQuit", commandWidgetClass, box, NULL, 0);
  XtAddCallback(quit, XtNcallback, destroy_widget, popup);
/*
  n = 0;
  XtSetArg(args[n], XtNfromHoriz, (XtArgVal) quit);  n++;
  update = XtCreateManagedWidget("popupUpdate", commandWidgetClass, box, 
				 args, n);
  XtAddCallback(quit, XtNcallback, update_port_stats, data); 
*/
  XtPopup(popup, XtGrabNone);
}


void
stat_update(w, data, closure)   /* don't use these args */
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  float f;
  int i;

  update_status();
  XtAppAddTimeOut(app_con, update * 1000, stat_update, NULL);
  redraw();
}


void 
update_port_stats(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  char *stats;
  
  stats = do_port_stats(data);
  
}
  

void 
set_mode(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  Arg arg;
  
  /*
   * the callback gets called twice, once for the set & once for the unset
   */

  if(dsp_mode == (int) data)
    return;
  else
    dsp_mode = (int) data;
  if((dsp_mode > num_dsp_modes) || (dsp_mode < 0))
    dsp_mode = DISPLAY_STATUS;
  update_status();
  redraw();
}


void
really_set_mode(w, id)
     Widget w;
     XtIntervalId *id;
{
  update_status();  
  redraw();
/*  XtDestroyWidget(w);  */
}


void 
set_protect(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  Arg arg;

  if(protect)
    protect = 0;
  else
    protect = 1;

  XtSetArg(arg, XtNlabel, (XtArgVal) protect ? "set  lock" : "unlocked");
  XtSetValues(w, &arg, 1);
}


void
change_community(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  make_prompt_popup(data, "community name:", community,
                    really_change_community);
  return;
}


void
really_change_community(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  char *nc = XawDialogGetValueString(data);

  if(community)
    free(community);

  if((community = (char *) malloc((strlen(nc) + 1) * sizeof(char))) ==
     (char *) NULL)
    return;

  strcpy(community, nc);
  XtDestroyWidget(XtParent((Widget) data));
  return;
}


void
save_text(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  make_prompt_popup(w, "filename:", "", really_save_text);
  return;
}


void
really_save_text(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  Widget parent  = XtParent((Widget) data);
  String cname   = XawDialogGetValueString(data);

/*
  if(XawAsciiSaveAsFile(data, cname))*/
    XtDestroyWidget(parent);

  return;
}


void
change_update(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  char value[16];

  sprintf(value, "%d", update);
  make_number_popup(data, "update interval:", value, really_change_update_box);
  return;
}


void
increment_number(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  String cname   = XawDialogGetValueString(data);
  Arg args[1];
  char value[16];
  int n;

  if(!isnumber(cname))
    {
      XBell(XtDisplay(w), 0);
      return;
    }

  n = atoi(cname) + 1;
  sprintf(value, "%d", n);
  XtSetArg(args[0], XtNvalue, value);
  XtSetValues(data, args, 1);
  return;
}


void
decrement_number(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  String cname   = XawDialogGetValueString(data);
  Arg args[1];
  char value[16];
  int n;

  if(!isnumber(cname))
    {
      XBell(XtDisplay(w), 0);
      return;
    }

  n = atoi(cname);
  if(n <= 10)
    {
      XBell(XtDisplay(w), 0);
      return;
    }
  --n;
  sprintf(value, "%d", n);
  XtSetArg(args[0], XtNvalue, value);
  XtSetValues(data, args, 1);
  return;
}




void
really_change_update_box(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  Widget parent  = XtParent((Widget) data);
  String cname   = XawDialogGetValueString(data);
  int n;

  if(!isnumber(cname))
    {
      XBell(XtDisplay(w), 0);
      return;
    }

  n = atoi(cname);
  if(n < 1)
    {
      XBell(XtDisplay(w), 0);
      return;
    }

  update = n;

  stat_update(w, data, closure);
  XtDestroyWidget(parent);
}


void
destroy_widget(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  XtDestroyWidget((Widget) data);
}


void 
quit(w, data, closure)
     Widget w;
     caddr_t data;
     caddr_t closure;
{
  exit(0);
}

