

#define XMEMC
#include "XmEmc.hh"
#undef XMEMC

int
main (int argc, char *argv[])
{
  Widget mainwindow = NULL;
  Widget menubar = NULL;
  Widget pane = NULL;
  Widget menu = NULL;
  Widget widget = NULL;

  XtAppContext app;

  XmString str;

  int i;

  toplevel = XtVaAppInitialize (&app,
				"XmEmc",
				NULL,
				0, &argc, argv, fallbackResources, NULL);

  mainwindow = XtVaCreateManagedWidget ("mainwindow",
					xmMainWindowWidgetClass, toplevel,
					XmNdeleteResponse, XmDESTROY,
					XmNtraversalOn, True, NULL);

  XtAddCallback (mainwindow, XmNdestroyCallback,
		 closeMainWindow, (XtPointer) NULL);

  menubar = XmCreateMenuBar (mainwindow, "menubar", NULL, 0);

  /*********************************/
  /* Create the File pulldown menu */
  /*********************************/

  menu = XmCreatePulldownMenu (menubar, "pulldown", NULL, 0);

  for (i = 0; fileMenu[i].label != NULL; i++)
    {
      widget = XtVaCreateManagedWidget (fileMenu[i].label,
					*(fileMenu[i].wClass),
					menu,
					XmNmarginWidth, 8,
					XmNmarginHeight, 8, NULL);

      if (fileMenu[i].mnemonic)
	XtVaSetValues (widget, XmNmnemonic, fileMenu[i].mnemonic, NULL);

      if (fileMenu[i].accelerator)
	{
	  str = XmStringCreateLocalized (fileMenu[i].accel_text);
	  XtVaSetValues (widget,
			 XmNaccelerator, fileMenu[i].accelerator,
			 XmNacceleratorText, str, NULL);
	  XmStringFree (str);
	}

      if (fileMenu[i].callback)
	{
	  XtAddCallback (widget,
			 XmNactivateCallback,
			 fileMenu[i].callback, fileMenu[i].callback_data);
	}

    }

  str = XmStringCreateLocalized ((char *) FILE_STR);
  filemenu = XtVaCreateManagedWidget (FILE_STR,
				      xmCascadeButtonWidgetClass, menubar,
				      XmNsubMenuId, menu,
				      XmNlabelString, str,
				      XmNmnemonic, FILE_MNEMONIC, NULL);
  XmStringFree (str);

  /*********************************/
  /* Create the Edit pulldown menu */
  /*********************************/

  menu = XmCreatePulldownMenu (menubar, "_pulldown", NULL, 0);

  for (i = 0; editMenu[i].label != NULL; i++)
    {
      widget = XtVaCreateManagedWidget (editMenu[i].label,
					*(editMenu[i].wClass),
					menu,
					XmNmarginWidth, 8,
					XmNmarginHeight, 8, NULL);

      if (editMenu[i].mnemonic)
	XtVaSetValues (widget, XmNmnemonic, editMenu[i].mnemonic, NULL);

      if (editMenu[i].accelerator)
	{
	  str = XmStringCreateLocalized (editMenu[i].accel_text);
	  XtVaSetValues (widget,
			 XmNaccelerator, editMenu[i].accelerator,
			 XmNacceleratorText, str, NULL);
	  XmStringFree (str);
	}

      if (editMenu[i].callback)
	{
	  XtAddCallback (widget,
			 XmNactivateCallback,
			 editMenu[i].callback, editMenu[i].callback_data);
	}
    }


  str = XmStringCreateLocalized ((char *) EDIT_STR);
  editmenu = XtVaCreateManagedWidget (EDIT_STR,
				      xmCascadeButtonWidgetClass, menubar,
				      XmNsubMenuId, menu,
				      XmNlabelString, str,
				      XmNmnemonic, EDIT_MNEMONIC, NULL);
  XmStringFree (str);


  /*********************************/
  /* Create the View pulldown menu */
  /*********************************/

  menu = XmCreatePulldownMenu (menubar, "_pulldown", NULL, 0);

  for (i = 0; viewMenu[i].label != NULL; i++)
    {
      widget = XtVaCreateManagedWidget (viewMenu[i].label,
					*(viewMenu[i].wClass),
					menu,
					XmNmarginWidth, 8,
					XmNmarginHeight, 8, NULL);

      if (viewMenu[i].mnemonic)
	XtVaSetValues (widget, XmNmnemonic, viewMenu[i].mnemonic, NULL);

      if (viewMenu[i].accelerator)
	{
	  str = XmStringCreateLocalized (viewMenu[i].accel_text);
	  XtVaSetValues (widget,
			 XmNaccelerator, viewMenu[i].accelerator,
			 XmNacceleratorText, str, NULL);
	  XmStringFree (str);
	}

      if (viewMenu[i].callback)
	{
	  XtAddCallback (widget,
			 XmNactivateCallback,
			 viewMenu[i].callback, viewMenu[i].callback_data);
	}
    }


  str = XmStringCreateLocalized ((char *) VIEW_STR);
  viewmenu = XtVaCreateManagedWidget (VIEW_STR,
				      xmCascadeButtonWidgetClass, menubar,
				      XmNsubMenuId, menu,
				      XmNlabelString, str,
				      XmNmnemonic, VIEW_MNEMONIC, NULL);
  XmStringFree (str);

  /*********************************/
  /* Create the Help pulldown menu */
  /*********************************/

  menu = XmCreatePulldownMenu (menubar, "_pulldown", NULL, 0);

  for (i = 0; helpMenu[i].label != NULL; i++)
    {
      widget = XtVaCreateManagedWidget (helpMenu[i].label,
					*(helpMenu[i].wClass),
					menu,
					XmNmarginWidth, 8,
					XmNmarginHeight, 8, NULL);

      if (helpMenu[i].mnemonic)
	XtVaSetValues (widget, XmNmnemonic, helpMenu[i].mnemonic, NULL);

      if (helpMenu[i].accelerator)
	{
	  str = XmStringCreateLocalized (helpMenu[i].accel_text);
	  XtVaSetValues (widget,
			 XmNaccelerator, helpMenu[i].accelerator,
			 XmNacceleratorText, str, NULL);
	  XmStringFree (str);
	}

      if (helpMenu[i].callback)
	{
	  XtAddCallback (widget,
			 XmNactivateCallback,
			 helpMenu[i].callback, helpMenu[i].callback_data);
	}
    }


  str = XmStringCreateLocalized ((char *) HELP_STR);
  helpmenu = XtVaCreateManagedWidget (HELP_STR,
				      xmCascadeButtonWidgetClass, menubar,
				      XmNsubMenuId, menu,
				      XmNlabelString, str,
				      XmNmnemonic, HELP_MNEMONIC, NULL);
  XmStringFree (str);

  XtVaSetValues (menubar, XmNmenuHelpWidget, helpmenu, NULL);
  XtManageChild (menubar);


  workArea =
    XtVaCreateManagedWidget ("workArea", xmFormWidgetClass, mainwindow,
			     XmNfractionBase, 40, NULL);

  pane = XtVaCreateWidget ("pane",
			   xmPanedWindowWidgetClass, workArea,
			   XmNsashWidth, 10,
			   XmNtopAttachment, XmATTACH_FORM,
			   XmNbottomAttachment, XmATTACH_NONE,
			   XmNleftAttachment, XmATTACH_NONE,
			   XmNrightAttachment, XmATTACH_FORM,
			   XmNsashHeight, 10, XmNtraversalOn, False, NULL);

  buttonform = XtVaCreateWidget ("form",
				 xmFormWidgetClass, pane,
				 XmNfractionBase, 220,
				 XmNtraversalOn, False, NULL);

  int rc = XpmCreatePixmapFromData (XtDisplay (toplevel),
				    DefaultRootWindow (XtDisplay (toplevel)),
				    estop,
				    &pixmap, 0, 0);

  rc +=
    XpmCreatePixmapFromData (XtDisplay (toplevel),
			     DefaultRootWindow (XtDisplay (toplevel)),
			     estop_off, &pixmap_off, 0, 0);

  Dimension width, height;

  if (rc == XpmSuccess)
    {

      /* The "estop" button */
      estopbutton = XtVaCreateManagedWidget (ESTOP_STR,
					     xmPushButtonWidgetClass,
					     buttonform, XmNtopAttachment,
					     XmATTACH_FORM,
					     XmNbottomAttachment,
					     XmATTACH_NONE, XmNleftAttachment,
					     XmATTACH_NONE,
					     XmNrightAttachment,
					     XmATTACH_FORM, XmNlabelPixmap,
					     pixmap, XmNlabelType, XmPIXMAP,
					     XmNshadowThickness, 4, NULL);
      XtVaGetValues (estopbutton, XmNwidth, &width, XmNheight, &height, NULL);
    }
  else
    {
      width = 78;
      height = 81;
      estopbutton = XtVaCreateManagedWidget (ESTOP_STR,
					     xmPushButtonWidgetClass,
					     buttonform, XmNtopAttachment,
					     XmATTACH_FORM,
					     XmNbottomAttachment,
					     XmATTACH_NONE, XmNleftAttachment,
					     XmATTACH_NONE,
					     XmNrightAttachment,
					     XmATTACH_FORM,
					     XmNshadowThickness, 4, XmNwidth,
					     width, XmNheight, height, NULL);
    }

  XtAddCallback (estopbutton, XmNarmCallback,
		 buttonsCB, (XtPointer) BT_ESTOP);


  // The "Machine" button
  machinebutton = XtVaCreateManagedWidget (MACHINE_STR,
					   xmPushButtonWidgetClass,
					   buttonform, XmNtopAttachment,
					   XmATTACH_WIDGET,
					   XmNbottomAttachment, XmATTACH_NONE,
					   XmNleftAttachment, XmATTACH_NONE,
					   XmNrightAttachment, XmATTACH_FORM,
					   XmNtopWidget, estopbutton,
					   XmNshadowThickness, 4,
					   XmNwidth, width, XmNheight, height,
					   NULL);

  XtAddCallback (machinebutton, XmNarmCallback,
		 buttonsCB, (XtPointer) BT_MACHINE);

  // Save the original colors so we can go back to this state. Only need one set for all buttons.
  XtVaGetValues (machinebutton, XmNtopShadowColor, &original_tsc,
		 XmNbottomShadowColor, &original_bsc,
		 XmNarmColor, &original_ac,
		 XmNbackground, &original_bg, NULL);

  // The "Abort" button
  abortbutton = XtVaCreateManagedWidget (ABORT_STR,
					 xmPushButtonWidgetClass, buttonform,
					 XmNtopAttachment, XmATTACH_WIDGET,
					 XmNbottomAttachment, XmATTACH_NONE,
					 XmNleftAttachment, XmATTACH_NONE,
					 XmNrightAttachment, XmATTACH_FORM,
					 XmNtopWidget, machinebutton,
					 XmNshadowThickness, 4,
					 XmNwidth, width, XmNheight, height,
					 XmNmappedWhenManaged, False, NULL);

  XtAddCallback (abortbutton, XmNarmCallback,
		 buttonsCB, (XtPointer) BT_ABORT);

  // The "Mist" button
  mistbutton = XtVaCreateManagedWidget (MIST_STR,
					xmPushButtonWidgetClass, buttonform,
					XmNtopAttachment, XmATTACH_WIDGET,
					XmNbottomAttachment, XmATTACH_NONE,
					XmNleftAttachment, XmATTACH_NONE,
					XmNrightAttachment, XmATTACH_FORM,
					XmNtopWidget, machinebutton,
					XmNsensitive, False,
					XmNshadowThickness, 4,
					XmNwidth, width, XmNheight, height,
#ifndef XMEMC_MIST
					XmNmappedWhenManaged, False,
#endif // XMEMC_MIST
					NULL);

  XtAddCallback (mistbutton, XmNarmCallback, buttonsCB, (XtPointer) BT_MIST);

  // The "Flood" button
  floodbutton = XtVaCreateManagedWidget (FLOOD_STR,
					 xmPushButtonWidgetClass, buttonform,
					 XmNtopAttachment, XmATTACH_WIDGET,
					 XmNbottomAttachment, XmATTACH_NONE,
					 XmNleftAttachment, XmATTACH_NONE,
					 XmNrightAttachment, XmATTACH_FORM,
					 XmNtopWidget, mistbutton,
					 XmNsensitive, False,
					 XmNshadowThickness, 4,
					 XmNwidth, width, XmNheight, height,
#ifndef XMEMC_FLOOD
					 XmNmappedWhenManaged, False,
#endif // XMEMC_FLOOD
					 NULL);

  XtAddCallback (floodbutton, XmNarmCallback,
		 buttonsCB, (XtPointer) BT_FLOOD);


  // The "brake" button
  brakebutton = XtVaCreateManagedWidget (BRAKE_STR,
					 xmPushButtonWidgetClass, buttonform,
					 XmNtopAttachment, XmATTACH_WIDGET,
					 XmNbottomAttachment, XmATTACH_NONE,
					 XmNleftAttachment, XmATTACH_NONE,
					 XmNrightAttachment, XmATTACH_FORM,
					 XmNtopWidget, floodbutton,
					 XmNsensitive, False,
					 XmNshadowThickness, 4,
					 XmNwidth, width, XmNheight, height,
#ifndef XMEMC_BRAKE
					 XmNmappedWhenManaged, False,
#endif // XMEMC_BRAKE
					 NULL);

  XtAddCallback (brakebutton, XmNarmCallback,
		 buttonsCB, (XtPointer) BT_BRAKE);

  // The "reset" button
  resetbutton = XtVaCreateManagedWidget (RESET_STR,
					 xmPushButtonWidgetClass, buttonform,
					 XmNtopAttachment, XmATTACH_WIDGET,
					 XmNbottomAttachment, XmATTACH_NONE,
					 XmNleftAttachment, XmATTACH_NONE,
					 XmNrightAttachment, XmATTACH_FORM,
					 XmNtopWidget, floodbutton,
					 XmNmappedWhenManaged, False,
					 XmNshadowThickness, 4,
					 XmNwidth, width,
					 XmNheight, height, NULL);

  pb = (XmPushButtonWidget) resetbutton;
  pb->pushbutton.armed = false;

  XtAddCallback (resetbutton, XmNarmCallback,
		 buttonsCB, (XtPointer) BT_RESET);

  /* ---------------------------------------------------------------- */

  XtVaSetValues (buttonform, XmNpaneMaximum, 800, XmNpaneMinimum, 200, NULL);

  XtManageChild (buttonform);


  XtManageChild (pane);

  Dimension x0 = 3;
  Dimension x1 = 30;
  Dimension y1 = 20;		// JRM was 5
  Dimension y2 = y1 + 5 * EMC_NUM_AXES + 4;
  Dimension boxMarginWidth = 5;
  Dimension boxMarginHeight = 5;

  jog_widget =
    JogControl (x0, x1, y1, y2, boxMarginWidth, boxMarginHeight, workArea,
		EMC_NUM_AXES);

  x0 = 1;
  x1 = 22;
  y1 = 30;
  y2 = 40;
  spindle_widget =
    SpindleControl (x0, x1, y1, y2, boxMarginWidth, boxMarginHeight,
		    workArea);

  createAxes ();
  createPosition ();
  createRunModes ();
  createScrolledText ();

  // Set up in Manual mode
  buttonsCB (manualMode, (XtPointer) MANUAL_MODE, (XtPointer) NULL);

  // Start off in the ESTOP condition.
  buttonsCB (estopbutton, (XtPointer) BT_ESTOP, (XtPointer) NULL);

  XtRealizeWidget (toplevel);

  XtAppMainLoop (app);
}

static void
closeMainWindow (Widget mw, XtPointer cd, XtPointer cb)
{
  (void) XtDestroyWidget ((Widget) toplevel);
  exit (0);
}

static void
fileMenuCB (Widget mw, XtPointer cd, XtPointer cb)
{
  int which = (int) cd;

  switch (which)
    {
    case FM_QUIT:
      // Avoid multiple popup syndrome
      if (!quitmenu)
	quitPopup (mw, (void *)QUIT_TITLE, cd);
      else
	RAISE_WIDGET (quitmenu);
      break;
    case FM_OPEN:
      // Avoid multiple popup syndrome
      if (!openfile)
	fileOpenPopup (mw, (void *)FILE_OPEN_TITLE, cd);
      else
	RAISE_WIDGET (openfile);
      break;
    case FM_NEW:
      break;
    case FM_SAVE_AS:
      // Avoid multiple popup syndrome
      if (!savefile)
	fileOpenPopup (mw, (void *)FILE_SAVE_TITLE, cd);
      else
	RAISE_WIDGET (savefile);
      break;
    case FM_SAVE:
      break;
    case FM_LOGGING:
      break;
    default:
      break;
    }
}

static void
editMenuCB (Widget mw, XtPointer cd, XtPointer cb)
{
  int which = (int) cd;

  switch (which)
    {
    case ED_EDIT:
      if (!editedit)
	fileOpenPopup (mw, (void *)EDIT_EDIT_TITLE, (XtPointer) cd);
      else
	RAISE_WIDGET (editedit);
      break;
    case ED_TOOLS:
      break;
    case ED_VARIABLES:
      break;
    case ED_CALIBRATION_0:
      break;
    case ED_CALIBRATION_1:
      break;
    case ED_CALIBRATION_2:
      break;
    default:
      break;
    }
}

static void
viewMenuCB (Widget mw, XtPointer cd, XtPointer cb)
{
  int which = (int) cd;

  switch (which)
    {
    case VW_DIAGS_0:
      break;
    case VW_DIAGS_1:
      break;
    case VW_DIAGS_2:
      break;
    default:
      break;
    }
}

static void
helpMenuCB (Widget mw, XtPointer cd, XtPointer cb)
{
  int which = (int) cd;

  switch (which)
    {
    case HM_HELP:
      break;
    case HM_ABOUT:
      // Avoid multiple popup syndrome
      if (!abouthelp)
	aboutPopup (mw, (void *)ABOUT_TEXT, cd);
      else
	RAISE_WIDGET (abouthelp);
      break;
    default:
      break;
    }
}

// These buttons can be called from anywhere (and hence not
// static (e.g., if the emc receives a hardware e-stop, it
// can call this routine to let the GUI reflect the condition.
// For instance: 
//
// buttonsCB (estopbutton, (XtPointer) BT_ESTOP, (XtPointer) NULL);
//
// would call the estop function.
//
void
buttonsCB (Widget mw, XtPointer cd, XtPointer cb)
{
  XmString valueLabel = NULL;
  switch ((int) cd)
    {
    case BT_MACHINE:
      TOGGLE (mw);

      if (isMachineOn)
	turnMachineOff ();
      else
	turnMachineOn ();

      // If the machine was off and now its on, do the following:
      if (isMachineOn)
	{
	  UNLOCK (brakebutton);
	  PRESS (brakebutton);
	  UNLOCK (mistbutton);
	  UNLOCK (floodbutton);
	  HIDE_MANUAL ();
	  HIDE_AUTO ();
	  HIDE_MDI ();
	  do_home ();
	}
      // If the machine was on and now its off, do the following:
      else
	{
	  turnMistOff ();
	  turnFloodOff ();
	  turnBrakeOn ();
	  hideSpindle ();
	  stopSpindle ();
	  jogDone ();

	  switch (runMode)
	    {
	    case MANUAL_MODE:
	      LOCK (brakebutton);
	      PRESS (brakebutton);
	      LOCK (mistbutton);
	      UNPRESS (mistbutton);
	      LOCK (floodbutton);
	      UNPRESS (floodbutton);
	      SHOW_MANUAL ();
	      break;
	    case AUTO_MODE:
	      SHOW_AUTO ();
	      HIDE (scrolledText);
	      break;
	    case MDI_MODE:
	      SHOW_MDI ();
	      HIDE (scrolledText);
	      break;
	    }
	}

      break;

    case BT_ABORT:
      wasAborted = True;
      isRunning = False;

      turnMachineOff ();
      HIDE (abortbutton);
      UNLOCK (machinebutton);
      UNPRESS (machinebutton);

      // Turn off all other that the AUTO might have turned on
      turnMistOff ();
      turnFloodOff ();
      turnBrakeOn ();
      stopSpindle ();
      hideSpindle ();

      LOCK (runModes);		// We want to see where it stopped, but not allow to continue
      LOCK (scrolledText);
      LOCK (pauseButton);
      LOCK (stepButton);
      valueLabel =
	XmStringCreateLtoR ((char *) ABORTED_STR, XmSTRING_DEFAULT_CHARSET);
      XtVaSetValues (runButton, XmNlabelString, valueLabel, NULL);
      XmStringFree (valueLabel);

      processAbort ();

      break;

    case BT_MIST:
      TOGGLE (mw);

      if (isMistOn)
	turnMistOff ();
      else
	turnMistOn ();

      break;
    case BT_FLOOD:
      TOGGLE (mw);

      if (isFloodOn)
	turnFloodOff ();
      else
	turnFloodOn ();

      break;
    case BT_BRAKE:
      TOGGLE (mw);

      if (isBrakeOn)
	{
	  turnBrakeOff ();
	  showSpindle ();
	}
      else
	{
	  turnBrakeOn ();
	  stopSpindle ();
	  hideSpindle ();
	}

      break;
    case BT_ESTOP:

      do_estop ();

      turnBrakeOn ();
      stopSpindle ();
      hideSpindle ();

      turnMachineOff ();
      turnMistOff ();
      turnFloodOff ();

      TOGGLE (mw);

      XtVaSetValues (mw, XmNlabelInsensitivePixmap, pixmap_off, NULL);

      LOCK (mw);

      PRESS (brakebutton);
      LOCK (brakebutton);

      UNPRESS (mistbutton);
      LOCK (mistbutton);

      UNPRESS (machinebutton);
      LOCK (machinebutton);

      UNPRESS (floodbutton);
      LOCK (floodbutton);

      jogDone ();

      setSpindleSpeed (INITIAL_SPINDLE_SPEED);
      run_finished ();
      call_resume ();
      unsetLimitOverride ();

      HIDE_MANUAL ();
      HIDE_AUTO ();
      HIDE_MDI ();
      SHOW (resetbutton);

      break;
    case BT_RESET:

      HIDE (resetbutton);
      TOGGLE (estopbutton);
      UNLOCK (estopbutton);

      // Act as if one pressed the Machine button if it's turned on
      SHOW (machinebutton);
      UNLOCK (machinebutton);
      if (isMachineOn)
	{
	  buttonsCB (machinebutton, (XtPointer) BT_MACHINE, (XtPointer) NULL);
	}

      break;

    case COORD_RELATIVE:

      if (!isCoordRelative)
	setCoordRelative ();
      break;

    case COORD_MACHINE:

      if (isCoordRelative)
	setCoordMachine ();
      break;

    case POSITION_ACTUAL:

      if (!isPosActual)
	setPosActual ();
      break;

    case POSITION_COMMANDED:

      if (isPosActual)
	setPosCommanded ();
      break;

    case DO_RUN:
      call_run ();
      break;

    case PAUSE_RESUME:
      if (!isPaused)
	call_pause ();
      else
	call_resume ();
      break;

    case STEP:
      call_step ();
      break;

    case LIMIT_OVERRIDE:
      setLimitOverride ();
      break;

    case JOG_BUTTON:
      showJogPopup ();
      break;

    case AUTO_MODE:
      if (runMode != AUTO_MODE)
	setModeAuto ();
      break;

    case MDI_MODE:
      if (runMode != MDI_MODE)
	setModeMDI ();
      break;

    case MANUAL_MODE:
      if (runMode != MANUAL_MODE)
	setModeManual ();
      break;
    }
}
static void
quitPopup (Widget push_button, XtPointer text, XtPointer cbs)
{
  XmString xm_string;
  XmString quit_string;
  XmString dont_quit_string;
  Arg args[5];

  xm_string =
    XmStringCreateLtoR ((char *) QUIT_QUESTION, XmFONTLIST_DEFAULT_TAG);
  XtSetArg (args[0], XmNmessageString, xm_string);
  quit_string = XmStringCreateLtoR (QUIT_STR, XmFONTLIST_DEFAULT_TAG);
  XtSetArg (args[1], XmNokLabelString, quit_string);
  dont_quit_string =
    XmStringCreateLtoR (DONT_QUIT_STR, XmFONTLIST_DEFAULT_TAG);
  XtSetArg (args[2], XmNcancelLabelString, dont_quit_string);

  // Note that Lesstif has overriding default button broken, but Motif works ok.
  XtSetArg (args[3], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON);

  XtSetArg (args[4], XmNtitle, text);

  quitmenu = XmCreateQuestionDialog (push_button, "areYouSure", args, 5);

  XmStringFree (xm_string);
  XmStringFree (quit_string);
  XmStringFree (dont_quit_string);

  XtUnmanageChild (XmMessageBoxGetChild (quitmenu, XmDIALOG_HELP_BUTTON));

  XtVaSetValues (XmMessageBoxGetChild (quitmenu, XmDIALOG_OK_BUTTON),
		 XmNshadowThickness, 4,
		 XmNmarginWidth, 12, XmNmarginHeight, 12, NULL);

  XtVaSetValues (XmMessageBoxGetChild (quitmenu, XmDIALOG_CANCEL_BUTTON),
		 XmNshadowThickness, 4,
		 XmNmarginWidth, 12, XmNmarginHeight, 12, NULL);

  XtAddCallback (quitmenu, (String) XmNokCallback,
		 (XtCallbackProc) reallyQuit, (XtPointer) cbs);
  XtAddCallback (quitmenu, (String) XmNcancelCallback, (XtCallbackProc) canc,
		 (XtPointer) cbs);

  XtManageChild (quitmenu);

  XtPopup (XtParent (quitmenu), XtGrabExclusive);
}

static void
fileOpenPopup (Widget push_button, XtPointer text, XtPointer cbs)
{
  XmString xm_string = NULL;
  XmString open_string = NULL;
  XmString dont_open_string = NULL;
  XmString filter_string = NULL;
  XmString filter_title = NULL;
  Arg args[6];
  int i;


  xm_string = XmStringCreateSimple ((char *) text);

  i = 0;
  XtSetArg (args[i], XmNmessageString, xm_string);
  i++;
  XtSetArg (args[i], XmNtitle, text);
  i++;
  // The following controls the width of the File Selection Box
  filter_title =
    XmStringCreateLtoR (FILTER_TITLE_STR, XmFONTLIST_DEFAULT_TAG);
  XtSetArg (args[i], XmNfilterLabelString, filter_title);
  i++;
  // The following is to make all the buttons taller.
  filter_string = XmStringCreateLtoR (FILTER_STR, XmFONTLIST_DEFAULT_TAG);
  XtSetArg (args[i], XmNapplyLabelString, filter_string);
  i++;

  switch ((int) cbs)
    {
    case FM_OPEN:
      open_string = XmStringCreateSimple (OPEN_STR);
      dont_open_string =
	XmStringCreateLtoR (DONT_OPEN_STR, XmFONTLIST_DEFAULT_TAG);
      XtSetArg (args[i], XmNokLabelString, open_string);
      i++;
      XtSetArg (args[i], XmNcancelLabelString, dont_open_string);
      i++;
      openfile =
	XmCreateFileSelectionDialog (push_button, "fileOpen", args, i);
      XmStringFree (open_string);
      XmStringFree (dont_open_string);

      THICKEN_FS_BUTTONS (openfile);
      POPUP_FILE_SELECTION_WIDGET (openfile, cbs);
      break;
    case FM_SAVE_AS:
      savefile =
	XmCreateFileSelectionDialog (push_button, "fileOpen", args, i);

      THICKEN_FS_BUTTONS (savefile);
      POPUP_FILE_SELECTION_WIDGET (savefile, cbs);
      break;
    case ED_EDIT:
      editedit =
	XmCreateFileSelectionDialog (push_button, "fileOpen", args, i);

      THICKEN_FS_BUTTONS (editedit);
      POPUP_FILE_SELECTION_WIDGET (editedit, cbs);
      break;
    }

  XmStringFree (filter_string);
  XmStringFree (xm_string);


}

static void
reallyQuit (Widget dialog, XtPointer x, XtPointer y)
{
  closeMainWindow (dialog, x, y);
}

static void
canc (Widget dialog, XtPointer cd, XtPointer cb)
{
  switch ((int) cd)
    {
    case FM_QUIT:
      (void) XtDestroyWidget (quitmenu);
      quitmenu = NULL;
      break;
    case FM_OPEN:
      (void) XtDestroyWidget (openfile);
      openfile = NULL;
      break;
    case FM_SAVE_AS:
      (void) XtDestroyWidget (savefile);
      savefile = NULL;
      break;
    case ED_EDIT:
      (void) XtDestroyWidget (editedit);
      editedit = NULL;
      break;
    case HM_ABOUT:
      (void) XtDestroyWidget (abouthelp);
      abouthelp = NULL;
      break;
    }
}
static void
fileOk (Widget dialog, XtPointer cd, XtPointer cb)
{
  char *mySelection = NULL;

// DO work here.
  switch ((int) cd)
    {
    case FM_OPEN:
      mySelection =
	XmTextGetString (XmFileSelectionBoxGetChild
			 (openfile, XmDIALOG_TEXT));
#ifdef DEBUG
      cout << "Openning " << mySelection << endl;
#endif
      (void) XtDestroyWidget (openfile);
      openfile = NULL;
      break;
    case FM_SAVE_AS:
      mySelection =
	XmTextGetString (XmFileSelectionBoxGetChild
			 (savefile, XmDIALOG_TEXT));
#ifdef DEBUG
      cout << "Saving as" << mySelection << endl;
#endif
      (void) XtDestroyWidget (savefile);
      savefile = NULL;
      break;
    case ED_EDIT:
      mySelection =
	XmTextGetString (XmFileSelectionBoxGetChild
			 (editedit, XmDIALOG_TEXT));
#ifdef DEBUG
      cout << "Editing" << mySelection << endl;
#endif
      (void) XtDestroyWidget (editedit);
      editedit = NULL;
      break;
    default:
      break;
    }

  if (mySelection)
    XtFree (mySelection);

}


static void
aboutPopup (Widget push_button, XtPointer text, XtPointer cbs)
{
  XmString xm_string;
  XmString about_string;
  Arg args[3];

  xm_string = XmStringCreateLtoR ((char *) text, XmFONTLIST_DEFAULT_TAG);
  XtSetArg (args[0], XmNmessageString, xm_string);
  about_string =
    XmStringCreateLtoR ((char *) ABOUT_OK, XmFONTLIST_DEFAULT_TAG);
  XtSetArg (args[1], XmNokLabelString, about_string);
  XtSetArg (args[2], XmNtitle, ABOUT_TITLE);

  abouthelp = XmCreateInformationDialog (push_button, "about", args, 3);
  XmStringFree (xm_string);
  XmStringFree (about_string);

  XtUnmanageChild (XmMessageBoxGetChild (abouthelp, XmDIALOG_CANCEL_BUTTON));
  XtUnmanageChild (XmMessageBoxGetChild (abouthelp, XmDIALOG_HELP_BUTTON));

  XtVaSetValues (XmMessageBoxGetChild (abouthelp, XmDIALOG_OK_BUTTON),
		 XmNshadowThickness, 4, NULL);

  XtAddCallback (abouthelp, (String) XmNokCallback, (XtCallbackProc) canc,
		 (XtPointer) cbs);
  XtManageChild (abouthelp);

  XtPopup (XtParent (abouthelp), XtGrabExclusive);
}

void
updateAxes (void)
{
  int i = 0;
  for (i = 1; i < EMC_NUM_AXES; i++)
    {
      axisPos[i] = getAxisValue (i);
      if (axisWidget[i])	// Just being cautious
	LABEL_AXIS_UPDATE (axisWidget[i], axisStr[i], axisPos[i]);
    }
}
void
showRunMode (void)
{
  if (isMachineOn && runModeForm)
    {
      XtVaSetValues (runModeForm, XmNmappedWhenManaged, True, NULL);
      switch (runMode)
	{
	case MANUAL_MODE:
	  SHOW_MANUAL ();
	  break;
	case AUTO_MODE:
	  SHOW_AUTO ();
	  break;
	case MDI_MODE:
	  SHOW_MDI ();
	  break;
	}
    }
  else
    hideRunMode ();		// Just to be sure
}

void
hideRunMode (void)
{
  if (axisForm)
    {
      XtVaSetValues (runModeForm, XmNmappedWhenManaged, False, NULL);
      XtVaSetValues (scrolledText, XmNmappedWhenManaged, False, NULL);
    }
}

static void
createAxes (void)
{
  if (axisForm != NULL)		// only build one set
    return;

  axisForm =
    XtVaCreateManagedWidget ("axisForm", xmFormWidgetClass, workArea,
			     XmNtopAttachment, XmATTACH_FORM,
			     XmNtopOffset, 5,
			     XmNbottomAttachment, XmATTACH_NONE,
			     XmNleftAttachment, XmATTACH_FORM,
			     XmNleftOffset, 5,
			     XmNrightAttachment, XmATTACH_NONE,
			     XmNmarginWidth, 5,
			     XmNmarginWidth, 5, XmNmarginHeight, 5, NULL);
  int i = 0;

  LABEL_AXIS (axisWidget[i], axisStr[i], axisPos[i], XmATTACH_FORM, NULL);


  for (i = 1; i < EMC_NUM_AXES; i++)
    {
      AXIS_SEPARATOR ();
      LABEL_AXIS (axisWidget[i], axisStr[i], axisPos[i], XmATTACH_WIDGET,
		  axisWidget[i - 1]);
    }

  AXIS_SEPARATOR ();
}

static void
createPosition (void)
{
  posForm =
    XtVaCreateManagedWidget ("form", xmFormWidgetClass, workArea,
			     XmNtopAttachment, XmATTACH_FORM,
			     XmNleftAttachment, XmATTACH_WIDGET,
			     XmNleftWidget, axisForm, XmNtopOffset, 5,
			     XmNbottomAttachment, XmATTACH_NONE,
			     XmNrightAttachment, XmATTACH_NONE,
			     XmNleftOffset, 5, XmNtraversalOn, False, NULL);

  XmString valueLabel =
    XmStringCreateLtoR ((char *) POSITION_STR, XmSTRING_DEFAULT_CHARSET);

  posLabel =
    XtVaCreateManagedWidget ("label", xmLabelWidgetClass, posForm,
			     XmNtopAttachment, XmATTACH_FORM,
			     XmNtopOffset, 25,
			     XmNbottomAttachment, XmATTACH_NONE,
			     XmNrightAttachment, XmATTACH_NONE,
			     XmNleftAttachment, XmATTACH_FORM,
			     XmNleftOffset, 50,
			     XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

  Arg args[12];			// Caution: increment to maximum value of "i" expected
  int i;

  i = 0;
  XtSetArg (args[i], XmNshadowThickness, 4);
  i++;
  pulldown = XmCreatePulldownMenu (posForm, "pulldown", args, i);

  actual = XtVaCreateManagedWidget (ACTUAL_STR,
				    xmPushButtonWidgetClass, pulldown,
				    XmNmarginWidth, 12,
				    XmNmarginHeight, 12,
				    XmNshadowThickness, 4, NULL);


  commanded = XtVaCreateManagedWidget (COMMANDED_STR,
				       xmPushButtonWidgetClass, pulldown,
				       XmNmarginWidth, 12,
				       XmNmarginHeight, 12,
				       XmNshadowThickness, 4, NULL);


  i = 0;
  XtSetArg (args[i], XmNleftAttachment, XmATTACH_FORM);
  i++;
  XtSetArg (args[i], XmNleftOffset, 25);
  i++;
  XtSetArg (args[i], XmNtopAttachment, XmATTACH_WIDGET);
  i++;
  XtSetArg (args[i], XmNtopWidget, posLabel);
  i++;
  XtSetArg (args[i], XmNtopOffset, 5);
  i++;
  XtSetArg (args[i], XmNorientation, XmVERTICAL);
  i++;
  XtSetArg (args[i], XmNsubMenuId, pulldown);
  i++;
  XtSetArg (args[i], XmNshadowThickness, 4);
  i++;

  position = XmCreateOptionMenu (posForm, POSITION_STR, args, i);

  XtManageChild (position);

  XtAddCallback (actual, XmNactivateCallback,
		 buttonsCB, (XtPointer) POSITION_ACTUAL);

  XtAddCallback (commanded, XmNactivateCallback,
		 buttonsCB, (XtPointer) POSITION_COMMANDED);


  i = 0;
  XtSetArg (args[i], XmNshadowThickness, 4);
  i++;
  pulldown = XmCreatePulldownMenu (posForm, "pulldown", args, i);

  relative = XtVaCreateManagedWidget (RELATIVE_COORD_STR,
				      xmPushButtonWidgetClass, pulldown,
				      XmNmarginWidth, 12,
				      XmNmarginHeight, 12,
				      XmNshadowThickness, 4, NULL);

  machine = XtVaCreateManagedWidget (MACHINE_COORD_STR,
				     xmPushButtonWidgetClass, pulldown,
				     XmNmarginWidth, 12,
				     XmNmarginHeight, 12,
				     XmNshadowThickness, 4, NULL);

  i = 0;
  XtSetArg (args[i], XmNleftAttachment, XmATTACH_FORM);
  i++;
  XtSetArg (args[i], XmNleftOffset, 25);
  i++;
  XtSetArg (args[i], XmNtopAttachment, XmATTACH_WIDGET);
  i++;
  XtSetArg (args[i], XmNtopWidget, position);
  i++;
  XtSetArg (args[i], XmNtopOffset, 5);
  i++;
  XtSetArg (args[i], XmNorientation, XmVERTICAL);
  i++;
  XtSetArg (args[i], XmNsubMenuId, pulldown);
  i++;
  XtSetArg (args[i], XmNshadowThickness, 4);
  i++;

  coordinates = XmCreateOptionMenu (posForm, "pulldown", args, i);

  XtManageChild (coordinates);

  XtAddCallback (relative, XmNactivateCallback,
		 buttonsCB, (XtPointer) COORD_RELATIVE);

  XtAddCallback (machine, XmNactivateCallback,
		 buttonsCB, (XtPointer) COORD_MACHINE);
}

static void
createRunModes (void)
{

  runModeForm =
    XtVaCreateManagedWidget ("form", xmFormWidgetClass, workArea,
			     XmNtopAttachment, XmATTACH_WIDGET,
			     XmNtopWidget, posForm, XmNtopOffset, 40,
			     XmNbottomAttachment, XmATTACH_NONE,
			     XmNrightAttachment, XmATTACH_NONE,
			     XmNleftAttachment, XmATTACH_FORM,
			     XmNleftOffset, 5,
			     XmNtraversalOn, False,
			     XmNmappedWhenManaged, False, NULL);

  XmString valueLabel =
    XmStringCreateLtoR ((char *) RUN_MODE_STR, XmSTRING_DEFAULT_CHARSET);

  Widget runLabel =
    XtVaCreateManagedWidget ("label", xmLabelWidgetClass, runModeForm,
			     XmNtopAttachment, XmATTACH_FORM,
			     XmNtopOffset, 25,
			     XmNbottomAttachment, XmATTACH_NONE,
			     XmNrightAttachment, XmATTACH_NONE,
			     XmNleftAttachment, XmATTACH_FORM,
			     XmNleftOffset, 5,
			     XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

  Arg args[12];			// Caution: increment to maximum value of "i" expected
  int i;

  i = 0;
  XtSetArg (args[i], XmNshadowThickness, 4);
  i++;
  pulldown = XmCreatePulldownMenu (runModeForm, "pulldown", args, i);

  autoMode = XtVaCreateManagedWidget (AUTO_STR,
				      xmPushButtonWidgetClass, pulldown,
				      XmNmarginWidth, 12,
				      XmNmarginHeight, 12,
				      XmNshadowThickness, 4, NULL);


  mdiMode = XtVaCreateManagedWidget (MDI_STR,
				     xmPushButtonWidgetClass, pulldown,
				     XmNmarginWidth, 12,
				     XmNmarginHeight, 12,
				     XmNshadowThickness, 4, NULL);

  manualMode = XtVaCreateManagedWidget (MANUAL_STR,
					xmPushButtonWidgetClass, pulldown,
					XmNmarginWidth, 12,
					XmNmarginHeight, 12,
					XmNshadowThickness, 4, NULL);


  i = 0;
  XtSetArg (args[i], XmNtopAttachment, XmATTACH_FORM);
  i++;
  XtSetArg (args[i], XmNleftAttachment, XmATTACH_WIDGET);
  i++;
  XtSetArg (args[i], XmNleftWidget, runLabel);
  i++;
  XtSetArg (args[i], XmNleftOffset, 5);
  i++;
  XtSetArg (args[i], XmNorientation, XmVERTICAL);
  i++;
  XtSetArg (args[i], XmNsubMenuId, pulldown);
  i++;
  XtSetArg (args[i], XmNshadowThickness, 4);
  i++;
  XtSetArg (args[i], XmNbuttonSet, 2);
  i++;

  runModes = XmCreateOptionMenu (runModeForm, "optionMenu", args, i);

  XtManageChild (runModes);

  XtAddCallback (autoMode, XmNactivateCallback,
		 buttonsCB, (XtPointer) AUTO_MODE);

  XtAddCallback (mdiMode, XmNactivateCallback,
		 buttonsCB, (XtPointer) MDI_MODE);

  XtAddCallback (manualMode, XmNactivateCallback,
		 buttonsCB, (XtPointer) MANUAL_MODE);

  valueLabel =
    XmStringCreateLtoR ((char *) RUN_STR, XmSTRING_DEFAULT_CHARSET);

  runButton =
    XtVaCreateManagedWidget ("button", xmPushButtonWidgetClass, runModeForm,
			     XmNtopAttachment, XmATTACH_FORM,
			     XmNtopOffset, 10,
			     XmNbottomAttachment, XmATTACH_NONE,
			     XmNrightAttachment, XmATTACH_NONE,
			     XmNleftAttachment, XmATTACH_WIDGET,
			     XmNleftWidget, runModes,
			     XmNleftOffset, 15,
			     XmNmarginWidth, 15,
			     XmNmarginHeight, 15,
			     XmNshadowThickness, 4,
			     XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

  XtAddCallback (runButton, XmNarmCallback, buttonsCB, (XtPointer) DO_RUN);

  XmPushButtonWidget pb;
  pb = (XmPushButtonWidget) runButton;
  pb->pushbutton.armed = false;

  valueLabel =
    XmStringCreateLtoR ((char *) PAUSE_STR, XmSTRING_DEFAULT_CHARSET);
  pauseButton =
    XtVaCreateManagedWidget ("button", xmPushButtonWidgetClass, runModeForm,
			     XmNtopAttachment, XmATTACH_FORM, XmNtopOffset,
			     10, XmNbottomAttachment, XmATTACH_NONE,
			     XmNrightAttachment, XmATTACH_NONE,
			     XmNleftAttachment, XmATTACH_WIDGET,
			     XmNleftWidget, runButton, XmNleftOffset, 15,
			     XmNmarginWidth, 15, XmNmarginHeight, 15,
			     XmNshadowThickness, 4, XmNmappedWhenManaged,
			     False, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

  XtAddCallback (pauseButton, XmNactivateCallback,
		 buttonsCB, (XtPointer) PAUSE_RESUME);

  valueLabel =
    XmStringCreateLtoR ((char *) STEP_STR, XmSTRING_DEFAULT_CHARSET);
  stepButton =
    XtVaCreateManagedWidget ("button", xmPushButtonWidgetClass, runModeForm,
			     XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget,
			     runButton, XmNtopOffset, 10, XmNbottomAttachment,
			     XmATTACH_NONE, XmNrightAttachment, XmATTACH_NONE,
			     XmNleftAttachment, XmATTACH_WIDGET,
			     XmNleftWidget, runModes, XmNleftOffset, 15,
			     XmNmarginWidth, 15, XmNmarginHeight, 15,
			     XmNshadowThickness, 4, XmNmappedWhenManaged,
			     False, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

  XtAddCallback (stepButton, XmNactivateCallback,
		 buttonsCB, (XtPointer) STEP);

  valueLabel =
    XmStringCreateLtoR ((char *) LIMIT_OVERRIDE_STR,
			XmSTRING_DEFAULT_CHARSET);
  limitOverride =
    XtVaCreateManagedWidget ("button", xmPushButtonWidgetClass, runModeForm,
			     XmNtopAttachment, XmATTACH_FORM, XmNtopOffset,
			     10, XmNbottomAttachment, XmATTACH_NONE,
			     XmNrightAttachment, XmATTACH_NONE,
			     XmNleftAttachment, XmATTACH_WIDGET,
			     XmNleftWidget, runModes, XmNleftOffset, 15,
			     XmNmarginWidth, 15, XmNmarginHeight, 15,
			     XmNshadowThickness, 4, XmNmappedWhenManaged,
			     False, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

  XtAddCallback (limitOverride, XmNactivateCallback,
		 buttonsCB, (XtPointer) LIMIT_OVERRIDE);

  valueLabel =
    XmStringCreateLtoR ((char *) JOG_STR, XmSTRING_DEFAULT_CHARSET);
  jogButton =
    XtVaCreateManagedWidget ("button", xmPushButtonWidgetClass, runModeForm,
			     XmNtopAttachment, XmATTACH_FORM, XmNtopOffset,
			     10, XmNbottomAttachment, XmATTACH_NONE,
			     XmNrightAttachment, XmATTACH_NONE,
			     XmNleftAttachment, XmATTACH_WIDGET,
			     XmNleftWidget, limitOverride, XmNleftOffset, 15,
			     XmNmarginWidth, 15, XmNmarginHeight, 15,
			     XmNshadowThickness, 4, XmNmappedWhenManaged,
			     False, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

  XtAddCallback (jogButton, XmNactivateCallback,
		 buttonsCB, (XtPointer) JOG_BUTTON);
}

static void
createScrolledText (void)
{
  Arg args[16];			// Caution, make sure i doesn't exceed this size
  int i = 0;

  XtSetArg (args[i], XmNtopAttachment, XmATTACH_WIDGET);
  i++;
  XtSetArg (args[i], XmNtopWidget, runModes);
  i++;
  XtSetArg (args[i], XmNtopOffset, 10);
  i++;
  XtSetArg (args[i], XmNleftAttachment, XmATTACH_FORM);
  i++;
  XtSetArg (args[i], XmNleftOffset, 5);
  i++;
  XtSetArg (args[i], XmNrightAttachment, XmATTACH_WIDGET);
  i++;
  XtSetArg (args[i], XmNrightWidget, buttonform);
  i++;
  XtSetArg (args[i], XmNrightOffset, 5);
  i++;
  XtSetArg (args[i], XmNbottomAttachment, XmATTACH_FORM);
  i++;
  XtSetArg (args[i], XmNbottomOffset, 5);
  i++;
  XtSetArg (args[i], XmNchildType, XmFRAME_WORKAREA_CHILD);
  i++;
  XtSetArg (args[i], XmNvisibleItemCount, 6);
  i++;

  scrolledText = XmCreateScrolledList (workArea, "scrolled_text", args, i);

  XtManageChild (scrolledText);
  XtVaSetValues (scrolledText, XmNmappedWhenManaged, False, NULL);

}

static void
restartList ()
{
  XmListDeleteAllItems (scrolledText);	// FIXME: Demo purposes only, clean out
  // FIXME: Instead, select the first line again, ready to start.
  HIDE (scrolledText);
}

/*************************************************************
 * The following are functions so we can insert appropriate  *
 * actions to keep the gui in sync with the real world. Only *
 * use these to modify these state-information globals.      *
 *************************************************************/

static void
turnMachineOn (void)
{
  isMachineOn = true;
#ifdef DEBUG
  cout << "Machine On" << endl;
#endif
}
static void
turnMachineOff (void)
{
  isMachineOn = false;
#ifdef DEBUG
  cout << "Machine Off" << endl;
#endif
}

static void
do_estop (void)
{
#ifdef DEBUG
  cout << endl << "ESTOP PRESSED" << endl << endl;
#endif
}

static void
turnBrakeOn (void)
{
  isBrakeOn = true;
#ifdef DEBUG
  cout << "Brake On" << endl;
#endif
}
static void
turnBrakeOff (void)
{
  isBrakeOn = false;
#ifdef DEBUG
  cout << "Brake Off" << endl;
#endif
}

static void
turnFloodOn (void)
{
  isFloodOn = true;
#ifdef DEBUG
  cout << "Flood On" << endl;
#endif
}

static void
turnFloodOff (void)
{
  isFloodOn = false;
#ifdef DEBUG
  cout << "Flood Off" << endl;
#endif
}

static void
turnMistOn (void)
{
  isMistOn = true;
#ifdef DEBUG
  cout << "Mist On" << endl;
#endif
}

static void
turnMistOff (void)
{
  isMistOn = false;
#ifdef DEBUG
  cout << "Mist Off" << endl;
#endif
}

static void
setCoordRelative (void)
{
  isCoordRelative = True;
#ifdef DEBUG
  cout << "Coordinates Relative" << endl;
#endif
}
static void
setCoordMachine (void)
{
  isCoordRelative = False;
#ifdef DEBUG
  cout << "Coordinates Machine" << endl;
#endif
}
static void
setPosActual (void)
{
  isPosActual = True;
#ifdef DEBUG
  cout << "Position Actual" << endl;
#endif
}
static void
setPosCommanded (void)
{
  isPosActual = False;
#ifdef DEBUG
  cout << "Position Commanded" << endl;
#endif
}

static void
call_run (void)
{
  isRunning = True;
  PRESS (runButton);
  LOCK (runButton);
  LOCK (runModes);
  HIDE (brakebutton);
  HIDE (mistbutton);
  HIDE (floodbutton);

  UNLOCK (pauseButton);
  SHOW (pauseButton);
  SHOW (abortbutton);
  LOCK (machinebutton);

  if (!isBrakeOn)
    {
      turnBrakeOn ();
      stopSpindle ();
      hideSpindle ();
    }

  XmString valueLabel =
    XmStringCreateLtoR ((char *) RUNNING_STR, XmSTRING_DEFAULT_CHARSET);
  XtVaSetValues (runButton, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

#ifdef DEBUG
  cout << "Called Run" << endl;
#endif
}

// The following would be called externally to make the run button available again.
void
run_finished (void)
{
  if (!isRunning)
    return;

  isRunning = False;

  XmString valueLabel = NULL;

  if (runButton)
    {
      TOGGLE (runButton);
      UNLOCK (runButton);
    }

  if (runModes)
    UNLOCK (runModes);
  if (pauseButton)
    HIDE (pauseButton);
  if (stepButton)
    HIDE (stepButton);
  if (scrolledText)
    restartList ();

  valueLabel =
    XmStringCreateLtoR ((char *) RUN_STR, XmSTRING_DEFAULT_CHARSET);
  XtVaSetValues (runButton, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

  SHOW_AUTO ();

}

static void
call_pause (void)
{
  XmString valueLabel =
    XmStringCreateLtoR ((char *) RESUME_STR, XmSTRING_DEFAULT_CHARSET);
  XtVaSetValues (pauseButton, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);
  valueLabel =
    XmStringCreateLtoR ((char *) PAUSED_STR, XmSTRING_DEFAULT_CHARSET);
  XtVaSetValues (runButton, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);
  isPaused = True;
  UNLOCK (stepButton);
  SHOW (stepButton);

#ifdef DEBUG
  cout << "We are paused" << endl;
#endif
}

static void
call_resume (void)
{
  if ((!isPaused) || (!pauseButton))
    return;
  XmString valueLabel =
    XmStringCreateLtoR ((char *) PAUSE_STR, XmSTRING_DEFAULT_CHARSET);
  XtVaSetValues (pauseButton, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);

  if (isRunning)
    valueLabel =
      XmStringCreateLtoR ((char *) RUNNING_STR, XmSTRING_DEFAULT_CHARSET);
  else
    valueLabel =
      XmStringCreateLtoR ((char *) RUN_STR, XmSTRING_DEFAULT_CHARSET);

  XtVaSetValues (runButton, XmNlabelString, valueLabel, NULL);
  XmStringFree (valueLabel);
  isPaused = False;
  HIDE (stepButton);
#ifdef DEBUG
  cout << "We are resumed" << endl;
#endif
}

static void
call_step (void)
{
#ifdef DEBUG
  cout << "Step" << endl;
#endif

  // For fun put stuff into msg area:
  XmString valueLabel =
    XmStringCreateLtoR ("G100 -- Move", XmSTRING_DEFAULT_CHARSET);
  XmListAddItemUnselected (scrolledText, valueLabel, 0);
  XmListSetBottomItem (scrolledText, valueLabel);
  XmStringFree (valueLabel);

}

static void
setLimitOverride (void)
{
  PRESS (limitOverride);
  LOCK (limitOverride);
  isLimitOverriden = True;
#ifdef DEBUG
  cout << "Set limit override" << endl;
#endif
}

static void
unsetLimitOverride (void)
{
  if (!isLimitOverriden)
    return;
  UNPRESS (limitOverride);
  UNLOCK (limitOverride);
  isLimitOverriden = False;
#ifdef DEBUG
  cout << "Unset limit override" << endl;
#endif
}

static void
showJogPopup (void)
{
#ifdef DEBUG
  cout << "Will popup Jog dialog or push to front if already up" << endl;
#endif
}
static void
setModeAuto (void)
{
  runMode = AUTO_MODE;
  HIDE_MANUAL ();
  HIDE_MDI ();
  SHOW_AUTO ();
#ifdef DEBUG
  cout << "Mode is Auto" << endl;
#endif
}

static void
setModeMDI (void)
{
  runMode = MDI_MODE;
  HIDE_MANUAL ();

  XtVaSetValues (scrolledText, XmNmappedWhenManaged, True, NULL);
  XtVaSetValues (runModes, XmNmenuHistory, mdiMode, NULL);
#ifdef DEBUG
  cout << "Mode is MDI" << endl;
#endif
}

static void
setModeManual (void)
{
  runMode = MANUAL_MODE;
  SHOW_MANUAL ();
#ifdef DEBUG
  cout << "Mode is Manual" << endl;
#endif
}

static void
do_home (void)
{
  XtVaSetValues (jog_widget, XmNmappedWhenManaged, True, NULL);
#ifdef DEBUG
  cout << "Do Home" << endl;
#endif
}

static void
processAbort (void)
{
  // TODO: put whatever is needed to be done on emc side to clean up
#ifdef DEBUG
  cout << "Process aborted" << endl;
#endif
}

double
getAxisValue (int i)
{
  int value = 0;

  // TODO: Call emc interface to obtain current value for i-th axis

  return value;
}

#ifdef NEED_GET_XM_TEXT
/* Utility to get text from an XmString. May not be needed, but handy */
static char *
getXmText (XmString aXmString)
{
  char *text;			/* Caller must Free ! */
  XmStringContext context;
  XmStringCharSet charset;
  XmStringDirection direction;
  Boolean separator;

  if (!XmStringInitContext (&context, aXmString))
    {
      if (context)
	XmStringFreeContext (context);
      return NULL;
    }
  while (XmStringGetNextSegment
	 (context, &text, &charset, &direction, &separator))
    {
      if (text != NULL)
	break;			/* Find first non-nil string */
    }

  if (context)
    XmStringFreeContext (context);
  if (charset)
    XtFree (charset);

  return text;
}
#endif
