/*
 * This file contains routines to draw and update the screen.
 *
 * 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/xstuff.c,v $
 *    $Author: tom $
 *    $Locker: tom $
 *    $Log:	xstuff.c,v $
 * Revision 1.2  90/08/19  16:19:18  tom
 * *** empty log message ***
 * 
 * Revision 1.1  90/08/15  01:13:17  tom
 * Initial revision
 * 
 */

#ifndef lint
static char *rcsid = "$Header: /afs/net.mit.edu/tools/src/xport/RCS/xstuff.c,v 1.2 90/08/19 16:19:18 tom Exp Locker: tom $";
#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/Cardinals.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/cursorfont.h>
#include <X11/Xaw/Dialog.h>
#include <X11/cursorfont.h>
#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/Sme.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/Repeater.h>
#include <X11/Xaw/ScrollbarP.h>


#include "expmap.h"
#include <mit-copyright.h>

static Pixmap exp[exp_num];
static Pixmap gray[gray_num];
static Pixmap mark;
static Pixmap authpixmap;
static Pixmap uparrow;
static Pixmap downarrow;

XtAppContext app_con;

/*
 *   Function:    draw_screen()
 *   Description: draws the initial screen
 *   Returns:     none
 */


void
draw_screen(argc, argv)
     int argc;
     char **argv;
{
  Widget panel;
  Widget panelPane;
  Widget sysLabel;
  Widget view; 
  Widget form;
  Widget labelW;
  Widget boardW = (Widget) NULL;
  Widget portW;
  Widget portCommand;
  Widget portBox = (Widget) NULL;
  Widget boardView;
  Widget button;
  Widget modeW;
  Widget dispForm;
  Widget dispBox;
  Widget labels[100];
  Cursor cursor;
  Arg args[5];
  char label[10];
  int  i, j, m, n, p;

  /*
   * initialize the application
   */

  panel          = XtAppInitialize(&app_con, "XPort", 
				   NULL, 0, 
				   &argc, argv, 
				   NULL, NULL, 0);


  /*
   * create the pixmaps for the explosions
   */

  for(i = 0; i < exp_num; i++)
    exp[i] = XCreateBitmapFromData (XtDisplay(panel),
				    XtScreen(panel)->root,
				    exp_bits[i],
				    exp_width, exp_height);

  /*
   * create some more
   */

  for(i = 0; i < gray_num; i++)
    gray[i] = XCreateBitmapFromData (XtDisplay(panel),
				    XtScreen(panel)->root,
				    gray_bits[i],
				    gray_width, gray_height);

  mark       = XCreateBitmapFromData(XtDisplay(panel), XtScreen(panel)->root,
                                     check_bits, check_width, check_height);
  authpixmap = XCreateBitmapFromData(XtDisplay(panel), XtScreen(panel)->root,
                                     auth_bits, auth_width, auth_height);
  uparrow    = XCreateBitmapFromData(XtDisplay(panel), XtScreen(panel)->root,
                                     up_bits, up_width, up_height);
  downarrow  = XCreateBitmapFromData(XtDisplay(panel), XtScreen(panel)->root,
                                     down_bits, down_width, down_height);


  /*
   * create the screen with lots o' windows. There's a paned widget
   * with a couple of forms in it.
   */

  panelPane      = XtCreateManagedWidget("panel", 
					 panedWidgetClass, panel, 
					 NULL, 0);

  /* 
   * the "titlebar"
   */

  form           = XtCreateManagedWidget("titleForm", 
					 formWidgetClass, panelPane, 
					 NULL, 0);

  XtSetArg(args[0], XtNlabel, (XtArgVal) sysdesc);
  sysLabel = XtCreateManagedWidget("sysDescr", commandWidgetClass, form, 
				   args, 1);
  XtAddCallback(sysLabel, XtNcallback, stat_device, NULL);

  /*
   * everything else (watch the bouncing pointer)
   */

  XtSetArg(args[0], XtNfromVert, (XtArgVal) form);
  form           = XtCreateManagedWidget("boardForm", 
					 formWidgetClass, panelPane, 
					 args, 1);

  /*
   * the left hand command panel
   */

  boardW         = XtCreateManagedWidget("commandForm", 
					 formWidgetClass, form, NULL, 0);

  /*
   * the display box
   */


  dispForm       = XtCreateManagedWidget("displayForm", 
					 formWidgetClass, boardW, NULL, 0);
 
  dispBox        = XtCreateManagedWidget("dispLabel", 
					 labelWidgetClass, dispForm, NULL, 0);

  for(i = 0; i < num_dsp_modes; i++)
    {
      XtSetArg(args[0], XtNfromVert, (XtArgVal) dispBox);
      dispBox        = XtCreateManagedWidget("displayBox", 
					     formWidgetClass, dispForm, 
					     args, 1);

      XtSetArg(args[0], XtNstate,      (XtArgVal) dsp_mode == i);
      XtSetArg(args[1], XtNradioData,  (XtArgVal) i);
      if(i > 0)
	XtSetArg(args[2], XtNradioGroup, (XtArgVal) modeW);
      modeW          = XtCreateManagedWidget("displayToggle", 
					     toggleWidgetClass, dispBox, 
					     args, i > 0 ? 3 : 2);
      XtAddCallback(modeW, XtNcallback, set_mode, i);

      XtSetArg(args[0], XtNfromHoriz, (XtArgVal) modeW);
      XtSetArg(args[1], XtNlabel, (XtArgVal) dsp_mode_labels[i]);
      XtCreateManagedWidget("displayLabel", labelWidgetClass, dispBox, 
			    args, 2);
    }
      
  XtSetArg(args[0], XtNfromVert, (XtArgVal) dispForm);
  dispBox        = XtCreateManagedWidget("commandBox", 
					 formWidgetClass, boardW, 
					 args, 1);
  
  /*
   * write protect toggle 
   */

  XtSetArg(args[0], XtNlabel, (XtArgVal) protect ? "set  lock" : "unlocked");
  modeW          = XtCreateManagedWidget("modeCommand", 
					 commandWidgetClass, dispBox, 
					 args, 1); 
  XtAddCallback(modeW, XtNcallback, set_protect, NULL);

  /*
   * update button
   */

  XtSetArg(args[0], XtNfromVert, (XtArgVal) modeW);
  modeW          = XtCreateManagedWidget("updateCommand", 
					 commandWidgetClass, dispBox, 
					 args, 1); 
  XtAddCallback(modeW, XtNcallback, change_update, modeW);

  /*
   * community button
   */

  XtSetArg(args[0], XtNfromVert, (XtArgVal) modeW);
  modeW          = XtCreateManagedWidget("communityCommand", 
					 commandWidgetClass, dispBox, 
					 args, 1); 
  XtAddCallback(modeW, XtNcallback, change_community, modeW);

  /*
   * restart button
   */

  XtSetArg(args[0], XtNfromVert, (XtArgVal) modeW);
  modeW          = XtCreateManagedWidget("restartCommand", 
					 commandWidgetClass, dispBox, 
					 args, 1); 
  XtAddCallback(modeW, XtNcallback, restart, NULL);

  /*
   * quit button
   */

  XtSetArg(args[0], XtNfromVert, (XtArgVal) modeW);
  button         = XtCreateManagedWidget("quitCommand", 
					 commandWidgetClass, dispBox, 
					 args, 1);
  XtAddCallback(button, XtNcallback, quit, NULL);


  /*
   * the right side
   */

  XtSetArg(args[0], XtNfromHoriz, (XtArgVal) boardW);
  boardView      = XtCreateManagedWidget("boardView", 
					 viewportWidgetClass, form, 
					 args, 1);
  form           = XtCreateManagedWidget("boardForm", 
					 formWidgetClass, boardView, NULL, 0);
  
  boardW = (Widget) NULL;

  /*
   * time to create the boards
   */

  i = -1;
  for(n = 1; n <= nboards; n*=2)
    {
      /*
       * first the label on top
       */

      XtSetArg(args[0], XtNfromHoriz, (XtArgVal) boardW);
      boardW = XtCreateManagedWidget("board", 
				    formWidgetClass, form, args, 1);
      if(!(nboards & n))
	{
	  XtSetArg(args[0], XtNlabel, (XtArgVal) "empty");
	  XtSetArg(args[1], XtNborderWidth, (XtArgVal) 0);
	  XtCreateManagedWidget("boardCommand", 
					    commandWidgetClass, boardW, 
					    args, 2);
	  continue;
	}
      else
	{
	  ++i;
	  XtSetArg(args[0], XtNlabel, (XtArgVal) board[i].name);
	  labels[i] = XtCreateManagedWidget("boardCommand", 
					    commandWidgetClass, boardW, 
					    args, 1);
	  XtAddCallback(labels[i], XtNcallback, stat_board, i+1);
	}
      /*
       * each port is a form with a button & a toggle inside 
       */

      portBox = labels[i];
      for (j = 0; j < board[i].nports; j++)
	{
	  	  printf("%d %d\n", i, j);

	  XtSetArg(args[0], XtNfromVert, (XtArgVal) portBox);
	  portBox     = XtCreateManagedWidget("portBox", 
					      formWidgetClass, boardW, 
					      args, 1);
	  
	  sprintf(label, "%2d", j+1);
	  XtSetArg(args[0], XtNlabel, (XtArgVal) label);
	  portCommand = XtCreateManagedWidget("portCommand", 
					      commandWidgetClass, portBox, 
					      args, 1);

	  XtAddCallback(portCommand, XtNcallback, stat_port,
			&(board[i].port[j]));
	  XtSetArg(args[0], XtNfromHoriz, (XtArgVal)  portCommand);
	  board[i].port[j].astatus.widget   = (caddr_t) 
	    XtCreateManagedWidget("port", toggleWidgetClass, portBox, args, 1);

	  XtSetArg(args[0], XtNfromHoriz, 
		   (XtArgVal) board[i].port[j].astatus.widget);
	  board[i].port[j].lstatus.widget   = (caddr_t)
	    XtCreateManagedWidget("port", toggleWidgetClass, portBox, args, 1);

	  XtSetArg(args[0], XtNfromHoriz, 
		   (XtArgVal) board[i].port[j].lstatus.widget);
	  board[i].port[j].nstatus.widget  = (caddr_t)
	    XtCreateManagedWidget("port", toggleWidgetClass, portBox, args, 1);

	  XtAddCallback(board[i].port[j].astatus.widget, XtNcallback, 
			set_port, &(board[i].port[j]));
	}
    }
  
  XtRealizeWidget(panel);
  redraw(); 

  /*
   * hack the geometries
   */

#ifndef NO_GEO_HACK
  i = -1;
  for(n = 1; n < nboards; n*=2)
    {
      if(!(nboards & n))
	continue;
      ++i;
      XtSetArg(args[0], XtNwidth,         (XtArgVal) &p);
      XtSetArg(args[1], XtNborderWidth,   (XtArgVal) &m);
      XtSetArg(args[2], XtNhorizDistance, (XtArgVal) &j);
      XtGetValues(XtParent(labels[i]), args, 3);
      XtSetArg(args[0], XtNwidth, (XtArgVal) p - 2*j - 2*m);
      XtSetValues(labels[i], args, 1);
    }

  XtSetArg(args[0], XtNwidth,         (XtArgVal) &p);
  XtSetArg(args[1], XtNborderWidth,   (XtArgVal) &m);
  XtSetArg(args[2], XtNhorizDistance, (XtArgVal) &j);
  XtGetValues(XtParent(dispForm), args, 3);
  XtSetArg(args[0], XtNwidth, (XtArgVal) p - 2*j -2*m);
  XtSetValues(dispForm, args, 1);

  /*
   * create the cursor
   */

  cursor = XCreateFontCursor(XtDisplay(panelPane), XC_hand1);
  XDefineCursor(XtDisplay(panelPane), XtWindow(panelPane), cursor);
#endif	 
  XtAppMainLoop(app_con);
}



/*
 *   Function:    redraw()
 *   Description: updates the port lights
 *   Returns:     none
 */

redraw()
{
  Arg arg[10];
  int i;
  int j;
  int n;

  i = -1;
  for(n = 1; n < nboards; n*=2)
    {
      if(!(nboards & n))
	continue;
      ++i;
      for(j = 0; j < board[i].nports; j++)
	{
	  if(dsp_mode == DISPLAY_STATUS)
	    {
	      XtSetArg(arg[0], XtNbackgroundPixmap, (XtArgVal) gray[0]); 
	      XtSetArg(arg[1], XtNsensitive, (XtArgVal) True);
	      XtSetArg(arg[2], XtNstate, (XtArgVal)
		       board[i].port[j].astatus.status == ADMIN_ON ? 1 : 0);
	      XtSetValues(board[i].port[j].astatus.widget, arg, 3);	    
	      
	      if(board[i].port[j].lstatus.status == LINK_NOSUPP)
		XtSetArg(arg[1], XtNsensitive, (XtArgVal) False);
	      else
		XtSetArg(arg[1], XtNstate, (XtArgVal) 
			 board[i].port[j].lstatus.status - 1);
	      XtSetValues(board[i].port[j].lstatus.widget, arg, 2);
	      
	      XtSetArg(arg[1], XtNsensitive, (XtArgVal) True);
	      XtSetArg(arg[2], XtNstate, (XtArgVal) 
		       board[i].port[j].nstatus.status == NETWORK_SEG ? 0 : 1);
	      XtSetValues(board[i].port[j].nstatus.widget, arg, 3);	    
	    }
	  
	  if(dsp_mode == DISPLAY_TRAFFIC)
	    {
	      XtSetArg(arg[0], XtNstate,  (XtArgVal) 0);
	      XtSetArg(arg[1], XtNbackgroundPixmap, 
		       (XtArgVal) 
		       gray[board[i].port[j].pkt_rate % (gray_num + 1)]);
	      XtSetValues(board[i].port[j].astatus.widget, arg, 2);
	      
	      XtSetArg(arg[1], XtNbackgroundPixmap, 
		       (XtArgVal) 
		       gray[board[i].port[j].xmit_coll_rate % (gray_num + 1)]);
	      XtSetArg(arg[2], XtNsensitive, (XtArgVal) True);
	      XtSetValues(board[i].port[j].lstatus.widget, arg, 3);
	      
	      XtSetArg(arg[1], XtNbackgroundPixmap, 
		       (XtArgVal) 
		       gray[board[i].port[j].recv_coll_rate % (gray_num + 1)]);
	      XtSetValues(board[i].port[j].nstatus.widget, arg, 2);	    
	    }
	}
    }
}



/*
 *   Function:    explode()
 *   Description: creates an explosion 
 *   Arguments:   Widget w:         widget to explode
 *                XtIntervalId *id: foolkit junk
 *   Returns:     none
 */

void
explode(w, id)
     Widget w;
     XtIntervalId *id;
{
  Arg arg[2];
  static int i = 0;

  if(i < exp_num)
    {
      XtSetArg(arg[0], XtNbitmap, (XtArgVal) exp[i]);
      XtSetValues(w, arg, 1);
      XtAppAddTimeOut(XtWidgetToApplicationContext(w), 100, explode, 
		      (caddr_t) w);
      ++i;
    }
  else
    {
      XtSetArg(arg[0], XtNbitmap, (XtArgVal) NULL);
      XtSetValues(w, arg, 1);
      XFlush(XtDisplay(w));
      i = 0;
    }
}


#ifdef notdef



make_legend(w)
     Widget w;
{
  Widget a, b, c;
  register int    i;
  CompositePart   *cwp;
  Arg args[3];

  if (XtIsComposite(w)) 
    {
      cwp = &(((CompositeWidget) w)->composite);
      for (i = 0; i < cwp->num_children; i++) 
	XtDestroyWidget(cwp->children[i]);
    }

  switch(mode)
    {
    case ADMIN:
      a = XtCreateManagedWidget("legendBox", boxWidgetClass, w, NULL, 0);
      XtSetArg(args[0], XtNlabel, "Active");
      XtCreateManagedWidget("legendLabel", labelWidgetClass, a, args, 1);
      XtCreateManagedWidget("legendDot", labelWidgetClass, a, NULL, 0);
      b = XtCreateManagedWidget("legendBox", boxWidgetClass, w, NULL, 0);
      XtSetArg(args[0], XtNlabel, "Inactive");
      XtCreateManagedWidget("legendLabel", labelWidgetClass, b, args, 1);
      XtCreateManagedWidget("legendDot", labelWidgetClass, b, NULL, 0);
      break;
    case LINK:
      a = XtCreateManagedWidget("legendBox", boxWidgetClass, w, NULL, 0);
      XtSetArg(args[0], XtNlabel, "Active");
      XtCreateManagedWidget("legendLabel", labelWidgetClass, a, args, 1);
      XtCreateManagedWidget("legendDot", labelWidgetClass, a, NULL, 0);
      b = XtCreateManagedWidget("legendBox", boxWidgetClass, w, NULL, 0);
      XtSetArg(args[0], XtNlabel, "Inactive");
      XtCreateManagedWidget("legendLabel", labelWidgetClass, b, args, 1);
      XtCreateManagedWidget("legendDot", labelWidgetClass, b, NULL, 0);
      c = XtCreateManagedWidget("legendBox", boxWidgetClass, w, NULL, 0);
      XtSetArg(args[0], XtNlabel, "foo");
      XtCreateManagedWidget("legendLabel", labelWidgetClass, c, args, 1);
      XtCreateManagedWidget("legendDot", labelWidgetClass, c, NULL, 0);
      break;
    case NETWORK:
      a = XtCreateManagedWidget("legendBox", boxWidgetClass, w, NULL, 0);
      XtSetArg(args[0], XtNlabel, "Active");
      XtCreateManagedWidget("legendLabel", labelWidgetClass, a, args, 1);
      XtCreateManagedWidget("legendDot", labelWidgetClass, a, NULL, 0);
      b = XtCreateManagedWidget("legendBox", boxWidgetClass, w, NULL, 0);
      XtSetArg(args[0], XtNlabel, "Inactive");
      XtCreateManagedWidget("legendLabel", labelWidgetClass, b, args, 1);
      XtCreateManagedWidget("legendDot", labelWidgetClass, b, NULL, 0);
      break;
    }
}
  

Widget
make_psb(w, text)
     Widget w;
     char   *text;
{
  Widget      popup;
  Widget      form;
  Widget      label;
  Widget      textW;
  Widget      box;
  Widget      quit;
  Widget      retry;
  Position    x, y;
  Dimension   width, height;
  Cardinal    n;
  Arg         args[10];

  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("psbPopup", transientShellWidgetClass, w,
			    args, n);

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

  n = 0;
  XtSetArg(args[n], XtNstring, text);                 n++;
  textW = XtCreateManagedWidget("psbText", asciiTextWidgetClass, form, 
			       args, n);

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

  quit = XtCreateManagedWidget("psbQuit", commandWidgetClass, box, NULL, 0);
  XtAddCallback(quit, XtNcallback, destroy_widget, popup);
  
  n = 0;
  XtSetArg(args[n], XtNfromHoriz, (XtArgVal) quit);   n++;
  retry = XtCreateManagedWidget("psbRetry", formWidgetClass, box, args, n);

  return(popup);
}

#endif




/*
 * Function:    void make_prompt_popup()
 * Arguments:   Widget w:           the parent of this popup
 *              char *label:        the dialog label
 *              char *stext*:       default value
 *              void (*callback)(): a function to call when user entered data
 * Description: A simple text prompt window
 */


void
make_prompt_popup(w, label, text, callback)
     Widget  w;
     char    *label;
     char    *text;
     void    (*callback)();
{
  Arg         args[5];
  Widget      popup, dialog;
  Position    x, y;
  Dimension   width, height;
  Cardinal    n;

  /*
   * guess where I stole this from
   */

  /*
   * 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, &width); n++;
  XtSetArg(args[1], XtNheight, &height); n++;
  XtGetValues(w, args, n);
  XtTranslateCoords(w, (Position) (width / 2), (Position) (height / 2),
                    &x, &y);

  n = 0;
  XtSetArg(args[n], XtNx, x);                         n++;
  XtSetArg(args[n], XtNy, y);                         n++;

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

  /*
   * The popup will contain a dialog box, prompting the user for input.
   */

  XtSetArg(args[0], XtNvalue, (XtArgVal) text);
  XtSetArg(args[1], XtNlabel, (XtArgVal) label);
  dialog = XtCreateManagedWidget("dialog", dialogWidgetClass, popup, args, 2);

  /*
   * The prompting message's size is dynamic; allow it to request resize.   
   */

  XawDialogAddButton(dialog, "ok", callback, dialog);
  XawDialogAddButton(dialog, "cancel", destroy_widget, (XtPointer) popup);

  XtPopup(popup, XtGrabNone);
}

/*
 * Function:    void make_number_popup()
 * Arguments:   Widget w:           the parent of this popup
 *              char *label:        title of window
 *              void (*callback)(): a function to call when user entered data
 * Description: A popup window for entering a number.
 */

void
make_number_popup(w, label, text, callback)
     Widget  w;
     char    *label;
     char    *text;
     void    (*callback)();
{
  Arg         args[5];
  Widget      popup, dialog;
  Widget      u, d;
  Position    x, y;
  Dimension   width, height;
  Cardinal    n;

  n = 0;
  XtSetArg(args[0], XtNwidth, &width); n++;
  XtSetArg(args[1], XtNheight, &height); n++;
  XtGetValues(w, args, n);
  XtTranslateCoords(w, (Position) (width / 2), (Position) (height / 2),
                    &x, &y);

  n = 0;
  XtSetArg(args[n], XtNx, x);                         n++;
  XtSetArg(args[n], XtNy, y);                         n++;

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

  /*
   * The popup will contain a dialog box, prompting the user for input.
   */

  XtSetArg(args[0], XtNvalue, (XtArgVal) text);
  XtSetArg(args[1], XtNlabel, (XtArgVal) label);
  dialog = XtCreateManagedWidget("dialog", dialogWidgetClass, popup, args, 2);

  XawDialogAddButton(dialog, "ok",     callback, dialog);
  XawDialogAddButton(dialog, "cancel", destroy_widget,   (XtPointer) popup);

  XtSetArg(args[0], XtNbitmap,    (XtArgVal) uparrow);
  u = XtCreateManagedWidget("upUpdateCommand", repeaterWidgetClass, dialog,
                            args, 1);
  XtAddCallback(u, XtNcallback, increment_number,  (XtPointer) dialog);

  XtSetArg(args[0], XtNbitmap,    (XtArgVal) downarrow);
  d = XtCreateManagedWidget("downUpdateCommand", repeaterWidgetClass, dialog,
                            args, 1);
  XtAddCallback(d, XtNcallback, decrement_number,  (XtPointer) dialog);

  XtPopup(popup, XtGrabNone);
}


void
make_label_popup(w)
     Widget w;
{
  Arg         args[5];
  Widget      popup;
  Widget      label;
  Widget      form;
  Widget      button;
  Position    x, y;
  Dimension   width, height;
  Cardinal    n;

  n = 0;
  XtSetArg(args[0], XtNwidth, &width); n++;
  XtSetArg(args[1], XtNheight, &height); n++;
  XtGetValues(w, args, n);
  XtTranslateCoords(w, (Position) (width / 2), (Position) (height / 2),
                    &x, &y);

  n = 0;
  XtSetArg(args[n], XtNx, x);                         n++;
  XtSetArg(args[n], XtNy, y);                         n++;

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

  form =   XtCreateManagedWidget("popupLabelForm", formWidgetClass, popup,
                                 args, 0);

  XtSetArg(args[0], XtNbitmap, (XtArgVal) authpixmap);
  label = XtCreateManagedWidget("popupLabelLabel", labelWidgetClass, form,
                                 args, 1);

  XtSetArg(args[0], XtNfromVert, (XtArgVal) label);
  button         = XtCreateManagedWidget("okCommand",
                                         commandWidgetClass, form,
                                         args, 1);
  XtAddCallback(button, XtNcallback, destroy_widget, popup);
  XtPopup(popup, XtGrabNone);
}


void
check_menu(menu)
     Widget menu;
{
  Arg arg[1];

  XtSetArg(arg[0], XtNleftBitmap, mark);
  XtSetValues(menu, arg, 1);
  return;
}


void
uncheck_menu(menu)
     Widget menu;
{
  Arg arg[1];

  XtSetArg(arg[0], XtNleftBitmap, None);
  XtSetValues(menu, arg, 1);
  return;
}
