/*

  Code for X-Pipe, X-Cntrl control panel

  $Revision: 1.3 $
  $Modtime:   28 Oct 1997 14:13:08  $

 12-03 RH/EHG DR 500002  Intel rounding change.
                    
*/

/*
#define ERMIF_DEBUG
*/

#include "glibc.h"
#include "xwidgets.h"
#if _HEADLESS
#include "midas.h"
#include "ermif.h"
#endif

static void cp_draw (XWIDGET *c, int index, int nelem);
static void cp_hilite (XWIDGET *c, int i, int j, int thick);
static void cp_next(XFACILITIES *Xf, XWIDGET *c, int dir);

#define OVERLAP(R1,R2) \
  (((R1).x <= (R2).x+(R2).w && (R1).x+(R1).w >= (R2).x) && \
   ((R1).y <= (R2).y+(R2).h && (R1).y+(R1).h >= (R2).y))

void mx_control_panel (XFACILITIES *Xf, int mode)
{

  XWIDGET con, *c;

  int mval, cstart;
  int i, j, n, la, ls;
  char type, temp[L_max_ascii], *s;
  bool pause, awake, no_arrow_move;
  bool monitor, move, exposure, resize;

  int_4 lval;
  real_4 fval;
  real_8 dval;
  bool_4 autorepeat;

#if _HEADLESS
  MRMSTRUCT *pMrm; 
  ERMIF_MSG Pack;
#endif

  cstart = Xf->cstatus;
  Xf->cstatus = 1;
  la = sizeof(con.label);
  c = (XWIDGET *)Xf->con.p;

  switch (mode) {

    case L_Interactive:
/* 18Sep97/jcw Comment out next line per OAF to address delays entering 
   control section
      mx_autorepeat(&autorepeat, -2);
*/
      no_arrow_move = Mx->no_arrow_move;
      Mx->no_arrow_move = TRUE;
      if (Xf->configure) mx_setbar("Configure panel...",18);
      Xf->cstatus = 0;

      /* check to see if an expose or a resize occurred while control */
      /* panel code was executing */
      if (Mx->exposure || Mx->resize) {
        mx_clear_window();
        cp_draw(c, 0, Xf->ncon);
        cp_hilite(c, 0, Xf->current, 0);
      }

      /* if keyboard focus is granted but toggled off, turn it back on */
      if (Xf->current < 0) {
        Xf->current = -Xf->current;
        cp_hilite(c, 0, Xf->current, 0);
      }

#if _HEADLESS
      pMrm = (MRMSTRUCT *)Xf->MRMPtr;
#endif

      /* check for control widget changes */
      while (Xf->cstatus==0 && !*Mcbreak) {

        pause = TRUE;
/*--------------------------------------------------
Sleepy Hollow
BEGIN MODS
--------------------------------------------------*/
#if _HEADLESS
        if (Xf->MRMMaster != -1){

	  if (ermif_get_msg(pMrm[Xf->MRMMaster].macro_number,&Pack) == 1)
          {
	    pause = FALSE;
            n = pMrm[Pack.index].offset-1;     /* n = Widget Offset */

            switch (Pack.type) 
            {
              case XCNTRL_GET_B:
                Pack.blocked = BLOCKING;
                                               /* Fall through to XCNTRL_GET */
              case XCNTRL_GET:
#ifdef ERMIF_DEBUG
printf("XCNTRL Get %s\n",pMrm[Pack.index].name);
#endif
                Pack.mrm_index = c[n].MWMIndex-1;

                switch (pMrm[Pack.index].dtype){
                  case    'L' : Pack.lval = c[n].val;
                                break;

                  case    'F' :
                  case    'D' :
                  case    'T' : Pack.dval = c[n].val;
                                break;

                  case    'A' :
                  case    'M' : dval = c[n].val;
                                type = m_rfind(c[n].label, temp, &dval,la, min(L_max_ascii,c[n].aval_len));
                                lval = dval;
                                ls   = min(lval, c[n].aval_len);
                                memset(Pack.str,0,ERMIF_STR_LEN);
                                strncpy(Pack.str,temp,min(ERMIF_STR_LEN,c[n].aval_len));
                                break;

                  default     :
                                break;
                }

                ermif_send_msg(ERMIF_MAIN,&Pack);
                break;

              case XCNTRL_SET:
#ifdef ERMIF_DEBUG
printf("XCNTRL Set %s\n",pMrm[Pack.index].name);
#endif
                switch (pMrm[Pack.index].dtype)
                {
                  case    'L' :
                                c[n].val=Pack.lval;                                /* Set NEW Value           */
                                if (isalpha(c[n].label[0])){                       /* If we have a RESULT     */
                                  m_lrslt(c[n].label,(int)c[n].val, la);           /* Set it....              */

                                  if (c[n].mask & xfc_disp){                       /* If we are VISIBLE       */
                                    mx_widget(&c[n], XW_UPDATE);                   /* Update the WIDGET       */
                                  }
                                }

                                if (c[n].mask & xfc_awake){                        /* Trigger the Callback    */
                                  Xf->cstatus = n+1;
                                }
                                break;
                  case    'F' :
                  case    'D' :
                                c[n].val=Pack.dval;
                                if (isalpha(c[n].label[0])){                      /* If we have a RESULT     */
                                  m_drslt(c[n].label, c[n].val, la);              /* Set it....              */
                                }
                                if (c[n].mask & xfc_disp){                        /* If we are VISIBLE       */
                                  mx_widget(&c[n], XW_UPDATE);                    /* Update the WIDGET       */
                                }

                                if (c[n].mask & xfc_awake){                       /* Trigger the Callback    */
                                  Xf->cstatus = n+1;
                                }
                                break;

                  case    'A' : {
                                int len_res,len_val;

                                len_res = strlen(c[n].label);
                                len_val = strlen(Pack.str);
                                m_arslt(c[n].label,Pack.str,len_res,len_val);
                                }
                                break;

                  default     :
                                printf("ERMIF: XCNTRL_SET unknown type %c\n",pMrm[Pack.index].dtype);
                                break;
                }
                break;

              case RESULT_GET_B:
              {
                char   type;
                char   temp[L_max_ascii];
                char   res_name[L_max_resname];
                int    lz = L_max_ascii;
                real_8 dval;

#ifdef ERMIF_DEBUG
printf("RESULT_GET_B %s\n",Pack.str);
#endif
                memset(res_name,0,L_max_resname);
                strcpy(res_name,Pack.str);

                type      = m_rfind(Pack.str,temp,&dval,la,lz);
                Pack.lval = (int)type;

                switch (type){
                  case 'A' : strncpy(Pack.str,temp,(int)dval);
                             Pack.str[(int)dval]=0;
                             break;

                  case 'B' :
                  case 'I' :
                  case 'L' :
                  case 'F' :
                  case 'D' : Pack.dval = dval;
                             break;

                  default  : printf("RESULT_GET_B result %s not found\n",res_name);
                             break;
                }

                Pack.blocked = BLOCKING;
                ermif_send_msg(ERMIF_MAIN,&Pack);
              }
                break;

	      case RESULT_GET:
              {
                char   type;
                char   temp[L_max_ascii];
                char   res_value[L_max_ascii];
                char   res_name[L_max_resname];
                int    lz = L_max_ascii;
                real_8 dval;

#ifdef ERMIF_DEBUG
printf("RESULT_GET %s\n",Pack.str);
#endif
                memset(res_value,0,L_max_ascii);
                memset(res_name,0,L_max_resname);
                strcpy(res_name,Pack.str);

                type      = m_rfind(res_name,temp,&dval,strlen(res_name),lz);
                Pack.lval = (int)type;

                memset(Pack.str,0,sizeof(Pack.str));

                switch (type){
                  case 'A' : strncpy(res_value,temp,(int)dval);
                             sprintf(Pack.str,"%c:%s %s",type,res_name,res_value);
                             break;

                  case 'B' :
                  case 'I' :
                  case 'L' : sprintf(Pack.str,"%c:%s %d",type,res_name,(int)dval);
                             break;

                  case 'F' :
                  case 'D' : sprintf(Pack.str,"%c:%s %lf",type,res_name,dval);
                             break;

                  default  : printf("RESULT_GET result %s not found\n",res_name);
                             break;
                }

                Pack.blocked = NON_BLOCKING;
                ermif_send_msg(ERMIF_MAIN,&Pack);
              }
                break;

              case RESULT_SET:
              {
                char   *pStr;
                char   type;        
                char   name[L_max_ascii];
                int    ln;
                int    ls;
                int    lval;
                double dval;
                char   sval[ERMIF_STR_LEN];

                sscanf(Pack.str,"%c:%s",&type,name);

                switch (type){
                  case 'A' : sscanf(Pack.str,"%c:%s %s",&type,name,sval);
                             pStr = strstr(Pack.str," ");
                             strcpy(sval,pStr+1);
                             ls = strlen(sval);
                             break;

                  case 'B' :
                  case 'I' :
                  case 'L' : sscanf(Pack.str,"%c:%s %d",&type,name,&lval);
                             break;

                  case 'F' :
                  case 'D' : sscanf(Pack.str,"%c:%s %lf",&type,name,&dval);
                             break;

                  default  : printf("RESULT_SET result type %c not supported\n",type);
                             break;
                }

#ifdef ERMIF_DEBUG
printf("Result Set %s\n",name);
#endif

                ln = strlen(name);
                switch (type)
                {
                  case 'A' : m_arslt(name,sval,ln,ls);
                             break;

                  case 'B' : m_brslt(name,(char)lval,ln);
                             break;

                  case 'I' : m_irslt(name,(short)lval,ln);
                             break;

                  case 'L' : m_lrslt(name,lval,ln);
                             break;

                  case 'F' : m_frslt(name,(float)dval,ln);
                             break;

                  case 'D' : m_drslt(name,dval,ln);
                             break;

                  default  :
                             break;
                }
              }
              break;
            }  /* switch(msg-type) */

          } /* if (ermif_get_msg() == 1) */

        } /* if (Xf->MRMMaster == 1)                        */
/*--------------------------------------------------
Sleepy Hollow
END MODS
--------------------------------------------------*/
#endif
        if (Xf->configure) cstart = Xf->ncon+1;
        else if (Xf->ncon>0) {
          cstart = max(cstart,0) + 1;
          pause = (cstart==1);
        }
        else cstart = 1;

        for (n=cstart-1;  !Xf->cstatus && n<Xf->ncon; ++n) {
          if (c[n].wtype && (c[n].mask&xfc_monitor)) {
            switch (c[n].wtype) {
              case XW_MENU:
                lval = c[n].val;
                if (c[n].id>0 && m_mwget(c[n].id,&lval)>0) {
                  c[n].val = lval;
                  if (c[n].mask&xfc_disp) mx_mval(&c[n], XW_UPDATE);
                  if (isalpha(c[n].label[0]))
                    m_lrslt(c[n].label, lval, la);
                  if (c[n].mask & xfc_awake)  Xf->cstatus = n + 1;

/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
#if _HEADLESS
                  if (Xf->MRMMaster != -1) {
                    if (pMrm[c[n].MWMIndex-1].attach_count>0){
                      Pack.type  = XCNTRL_SET;
                      Pack.dval  = c[n].val;
                      Pack.index = n;
                      Pack.blocked = NON_BLOCKING;
                      Pack.mrm_index = c[n].MWMIndex-1;
                      ermif_send_msg(ERMIF_MAIN,&Pack);
                    }
                  }
#endif
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/

                }
                break;

              case XW_VALUATOR:
                if (c[n].id>0 && m_dwget(c[n].id,&c[n].val)>0) {
                  if (c[n].mask & xfc_disp) mx_dflval(&c[n], XW_UPDATE);
                  if (isalpha(c[n].label[0])) m_drslt(c[n].label, c[n].val, la);
                  if (c[n].mask & xfc_awake) Xf->cstatus = n + 1;

/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
#if _HEADLESS
                  if (Xf->MRMMaster != -1) {
                    if (pMrm[c[n].MWMIndex-1].attach_count>0){
                      Pack.type  = XCNTRL_SET;
                      Pack.dval  = c[n].val;
                      Pack.index = n;
                      Pack.blocked = NON_BLOCKING;
                      Pack.mrm_index = c[n].MWMIndex-1;
                      ermif_send_msg(ERMIF_MAIN,&Pack);
                    }
                  }
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/
#endif
                }
                break;

              case XW_MSGMONITOR:
                mx_msgval_poll(&c[n]);
                if (c[n].val>0 && (c[n].mask & xfc_awake)) Xf->cstatus = n + 1;
                break;

              default:
                if (c[n].dtype=='T') {
                  real_4 elapsed;
                  if (c[n].u.av.time < 0) {
                    m_secnds(0.0, &elapsed);
                    if (c[n].pause <= 0)
                      dval = elapsed;
                    else
                      dval = floor(0.5 + elapsed/c[n].pause) * c[n].pause;
                    dval = floor(0.5 + dval*100) / 100;
/* DR 500002  Intel rounding issue                    
		    Orignal
		    if (c[n].val != dval) */
                    if (fabs(c[n].val-dval) >= 0.000001) {

                      c[n].val = dval;
                      if (isalpha(c[n].label[0]))
                        m_drslt(c[n].label,c[n].val,la);
                      if (c[n].mask & xfc_disp)
                        i = mx_aval(&c[n], XW_UPDATE);
                      if (c[n].mask & xfc_awake)
                        Xf->cstatus = n + 1;

/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
#if _HEADLESS
                      if (Xf->MRMMaster != -1) {
                        if (pMrm[c[n].MWMIndex-1].attach_count>0){
                          Pack.type  = XCNTRL_SET;
                          Pack.dval  = c[n].val;
                          Pack.index = n;
                          Pack.blocked = NON_BLOCKING;
                          Pack.mrm_index = c[n].MWMIndex-1;
                          ermif_send_msg(ERMIF_MAIN,&Pack);
                        }
                      }
#endif
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/
                    }
                  }
                  else if (c[n].val > 0) {
                    m_secnds(c[n].u.av.time, &elapsed);
                    if (elapsed > c[n].pause || elapsed > c[n].val) {
                      c[n].val -= elapsed;
                      c[n].val = max(0, c[n].val);
                      if (isalpha(c[n].label[0]))
                        m_drslt(c[n].label, c[n].val, la);
                      if (c[n].mask & xfc_disp) {
                        dval = c[n].val;
                        if (c[n].pause > 0)
                          c[n].val = floor(0.5 + dval/c[n].pause) * c[n].pause;
                        c[n].val = floor(0.5 + c[n].val*100) / 100;
                        i = mx_aval(&c[n], XW_UPDATE);
                        c[n].val = dval;
                      }
                      if (c[n].val == 0 && (c[n].mask & xfc_awake)) {
                        Xf->cstatus = n + 1;
                      }
                      c[n].u.av.time += elapsed;
/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
#if _HEADLESS
                      if (Xf->MRMMaster != -1) {
                        if (pMrm[c[n].MWMIndex-1].attach_count>0){
                          Pack.type  = XCNTRL_SET;
                          Pack.dval  = c[n].val;
                          Pack.index = n;
                          Pack.blocked = NON_BLOCKING;
                          Pack.mrm_index = c[n].MWMIndex-1;
                          ermif_send_msg(ERMIF_MAIN,&Pack);
                        }
                      }
#endif
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/
                    }
                  }
                }
                else if (isalpha(c[n].label[0])) {
                  bool change=FALSE;
                  dval = c[n].val;
                  type = m_rfind(c[n].label, temp, &dval,la, min(L_max_ascii,c[n].aval_len));
                  lval = dval;
                  ls   = min (lval, c[n].aval_len);

                /* Both numeric values */
                  if (type>'A' && c[n].dtype>'A'){
                    change = (c[n].val != dval);
#if _HEADLESS
/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
                    if (Xf->MRMMaster != -1) {
                      if ((pMrm[c[n].MWMIndex-1].attach_count>0)&&(change)){
                        Pack.type  = XCNTRL_SET;
                        Pack.dval  = dval;
                        Pack.index = 1;
                        Pack.blocked = NON_BLOCKING;
                        Pack.mrm_index = c[n].MWMIndex-1;
                        ermif_send_msg(ERMIF_MAIN,&Pack);
                      }
                    }
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/
#endif
                  }
                /* Both ASCII strings  */
	          else if (type=='A' && c[n].dtype=='A'){
                    change = (c[n].val!=dval ||
                          (ls>0 && strncmp(temp,(char *)c[n].aval.p,ls)) );
#if _HEADLESS
/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
                    if (Xf->MRMMaster != -1) {
                      if ((pMrm[c[n].MWMIndex-1].attach_count>0)&&(change)){
                        memset(Pack.str,0,ERMIF_STR_LEN);
                        strncpy(Pack.str,temp,min(ERMIF_STR_LEN,c[n].aval_len));
                        Pack.type  = XCNTRL_SET;
                        Pack.dval  = c[n].val;
                        Pack.index = 2;
                        Pack.blocked = NON_BLOCKING;
                        Pack.mrm_index = c[n].MWMIndex-1;
                        ermif_send_msg(ERMIF_MAIN,&Pack);
                      }
                    }
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/
#endif
                  }

                  if (change) {
                    c[n].val = dval;
                    if (type=='A')
                      strncpy((char *)c[n].aval.p, temp,min(L_max_ascii,c[n].aval_len));
                    if (c[n].mask & xfc_disp) i = mx_aval(&c[n], XW_UPDATE);
                    if (c[n].mask & xfc_awake) Xf->cstatus = n + 1;
                  }
                }
                break;
            }
          }
        }
        cstart = 0;

            /* handle events */
        if (!Xf->cstatus && mx_ifevent()){

PROCESSEVENT:
          pause = FALSE;
          if (Mx->breakflag){
            Xf->cstatus = -1;
          }else if (Mx->key_press || Mx->motion_notify || Mx->button_press) {

            if (Mx->button_press==3||(Mx->button_press==2 && !Xf->configure)) {
              n = -1;                   /* main control panel menu */
            }else if (Mx->key_press) {
              n = Xf->current-1;        /* keypress to current KB focus */
            }else {
              int x = Mx->xpos, y = Mx->ypos;
              for (n=Xf->ncon-1; n>=0; --n) {
                if (c[n].wtype!=XW_NONE && (c[n].mask&xfc_disp) &&
                   (Xf->configure || (c[n].mask&xfc_edit)) &&
                    x >= c[n].x && x <= c[n].x+c[n].w &&
                    y >= c[n].y && y <= c[n].y+c[n].h)
                  break;
              }
              if (n>=0 && n+1!=Xf->current &&
                  (c[n].mask&xfc_mfocus) && (c[n].mask&xfc_edit)) {
                cp_hilite(c, Xf->current, n+1, 0);
                Xf->current = n+1;
              }
            }

            /* If the event processed did not occur in the last menu */
            /* entered, make sure it unhilites its menu item. */

            if (Xf->cmenulit && n+1!=Xf->cmenulit) {
              i = Xf->cmenulit - 1;
              (void)mx_mval(&c[i], XW_UNHILITE);
              Xf->cmenulit = 0;
            }

            if ((Mx->key_char=='\t' || Mx->key_char==' ') && Xf->ncon>0){ /* move KB focus */
              cp_next(Xf, c, (Mx->state_mask & L_ShiftKeyMask) ? -1 : 1);
            }else if (n<0){	
              if (Mx->key_upchar == '?')		      /* Help */
                mx_mhelp("~CONTROL PANEL","Control Panel", 14, 13);

            else if (Mx->key_upchar=='Q')		      /* Exit */
              Xf->cstatus = -1;
							      /* Panel Menu */
            else if (Mx->key_upchar=='M' || Mx->button_press>=2) {
/*+++       */
/* DR 11175 */
              if (Mx->disable_menu == 0) {
/*---       */
                strcpy(temp,"~CONTROL PANEL;Refresh,- Configure,Learn,Font Size...,Exit Controls");
                if (Xf->configure) temp[23] = '+';
                switch (mx_menu(0,temp,strlen(temp))) {
                  case 1:			/* Refresh */
                    Mx->exposure = TRUE;
                    break;
                  case 2: 			/* Toggle Configure */
                    Xf->configure = !Xf->configure;
                    if (Xf->configure) mx_setbar("Configure panel...",18);
                    else mx_unsetbar();
                    if (Xf->configure && Xf->cmenulit) {
                      i = Xf->cmenulit - 1;
                      (void)mx_mval(&c[i], XW_UNHILITE);
                      Xf->cmenulit = 0;
                    }
                    break;
                  case 3:
                    Xf->cstatus = -999;
                    break;
                  case 4:			/* Font Size */
                    lval = Mx->text_w;
                    mx_lprompt("Font Width: ", &lval, 12);
                    if (lval != Mx->text_w) {
                      mx_setfont(lval);
                      Mx->resize = TRUE;
                    }
                    break;
                  case 5:			/* Exit */
                    Xf->cstatus = -1;
                    break;
                }
/*+++       */
/* DR 11175 */
              }
/*---       */
            }
			      /* Drag panel widget */
          }

          else if (Xf->configure && !(Mx->button_press==2 &&
                  (c[n].wtype==XW_MENU || c[n].wtype==XW_VALUATOR))) {

            if (Mx->button_press==1) {
              int_4 x2, y2;
              XRectangle r;

              r.x = c[n].x; r.width = c[n].w;
              r.y = c[n].y; r.height = c[n].h;
              cp_hilite(c, Xf->current, 0, 0);
              if (c[n].wtype==XW_FRAME) {
                x2 = r.x + r.width;
                y2 = r.y + r.height;
                mx_rubberwarpbox(&c[n].x, &c[n].y, &x2, &y2, NULL);
                c[n].w = x2 - c[n].x;
                c[n].h = y2 - c[n].y;
              }
              else {
                x2 = Mx->width - r.width - 1;
                y2 = Mx->height - r.height - 1;
                mx_dragbox(&c[n].x,&c[n].y,c[n].w,c[n].h,0,x2,0,y2,NULL);
              }
              if (Mx->button_release==1) {
                Region over;
                mx_clear_area(r.x, r.y, r.width, r.height);
                over = XCreateRegion();
                XUnionRectWithRegion(&r, over, over);
                for (i=0; i < Xf->ncon; i++) {
                  if (c[i].wtype!=XW_NONE && (c[i].mask&xfc_disp) &&
                     (i==n || XRectInRegion(over,c[i].x,c[i].y,
                    c[i].w,c[i].h)!=RectangleOut)) {
                    r.x = c[i].x; r.width = c[i].w;
                    r.y = c[i].y; r.height = c[i].h;
                    cp_draw(c, i, 1);
                    XUnionRectWithRegion(&r, over, over);
                  }
                }
                XDestroyRegion(over);
              }
              else {
                c[n].x = r.x; c[n].w = r.width;
                c[n].y = r.y; c[n].h = r.height;
              }
              cp_hilite(c, 0, Xf->current, 0);
            }
            else if (Mx->key_press) XBell(G.D, 50);

         }
	 /* Menu, xVal or Prompt oneshot */
         else if (!Mx->motion_notify || c[n].wtype==XW_MENU) {
            move = FALSE;
            if (Mx->button_press==1 && Xf->current!=n+1) {
              cp_hilite(c, Xf->current, n+1, 0);
              Xf->current = n+1;
            }
            awake = (Xf->current==n+1 && !Mx->motion_notify);
            if (awake) cp_hilite(c, 0, n+1, 1);
              switch (c[n].wtype) {
                case XW_MENU:			/* menu event */
                  lval = c[n].val;
                  if (mx_mval(&c[n],XW_EVENT)) {	/* if changed */
                    if (isalpha(c[n].label[0]))
                      m_lrslt(c[n].label, (int)c[n].val, la);
                    if (c[n].mask & xfc_awake)
                      Xf->cstatus = n+1;

#if _HEADLESS
/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
                    if (Xf->MRMMaster != -1) {
                      if (pMrm[c[n].MWMIndex-1].attach_count>0){
                        Pack.type  = XCNTRL_SET;
                        Pack.dval  = c[n].val;
                        Pack.index = n;
                        Pack.blocked = NON_BLOCKING;
                        Pack.mrm_index = c[n].MWMIndex-1;
                        ermif_send_msg(ERMIF_MAIN,&Pack);
                      }
                    }
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/
#endif
                  }
                  if (c[n].u.mv.lit) Xf->cmenulit = n+1;
                  break;

                case XW_PROMPT:			/* prompt event */
                  if (Mx->key_press!=0 && Mx->key_press!=13) {
                    if (Mx->key_upchar != '?') XBell(G.D, 50);
                    else mx_mhelp("PROMPT", (char *)c[n].title.p,
                      6, c[n].title_len);
                  }
                  else {
                    ls = min(L_max_ascii, c[n].aval_len);
                    m_move((void *)c[n].aval.p, temp, ls);
                    dval = c[n].val;
                    lval = mx_aval(&c[n], XW_EVENT);
                    if (c[n].dtype=='T') {
                      if (c[n].u.av.time >= 0) m_secnds(0.0, &c[n].u.av.time);
                    }
                    else if (strncmp(temp, (char *)c[n].aval.p, ls)) {
                      lval = min(L_max_ascii, max(1,lval));
                      m_move((void *)c[n].aval.p, temp, lval);
                      if (c[n].dtype == ' ') {
                        if (m_a2d((char *)c[n].aval.p,&c[n].val,lval)>0)
                          c[n].dtype = 'D';
                        else
                          c[n].dtype = 'A';
                      }
                      if (c[n].dtype=='A') {
                        c[n].val = lval;
                        if (isalpha(c[n].label[0]))
                          m_arslt(c[n].label, temp, la, lval);
                        if (c[n].mask & xfc_awake) Xf->cstatus = n+1;
#if _HEADLESS
/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
                        if (Xf->MRMMaster != -1) {
                          if (pMrm[c[n].MWMIndex-1].attach_count>0){
                            Pack.type  = XCNTRL_SET;
                            memset(Pack.str,0,sizeof(Pack.str));
                            strncpy(Pack.str,temp,lval);
                            Pack.index = n;
                            Pack.blocked = NON_BLOCKING;
                            Pack.mrm_index = c[n].MWMIndex-1;
                            ermif_send_msg(ERMIF_MAIN,&Pack);
                          }
                        }
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/
#endif
                     }
                      else if (c[n].val != dval) {
                        if (isalpha(c[n].label[0]))
                          m_drslt(c[n].label, c[n].val, la);
                        if (c[n].mask & xfc_awake) Xf->cstatus = n+1;
#if _HEADLESS
/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
                        if (Xf->MRMMaster != -1) {
                          if (pMrm[c[n].MWMIndex-1].attach_count>0){
                            Pack.type  = XCNTRL_SET;
                            Pack.dval  = c[n].val;
                            Pack.index = n;
                            Pack.blocked = NON_BLOCKING;
                            Pack.mrm_index = c[n].MWMIndex-1;
                            ermif_send_msg(ERMIF_MAIN,&Pack);
                          }
                         }
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/
#endif
                      }
                    }
                  }
                  break;

                case XW_VALUATOR:		       /* dval event */
                  dval = c[n].val;
                  mx_dflval(&c[n], XW_EVENT);
                  if (dval != c[n].val) {		/* if  changed */
                    if (isalpha(c[n].label[0]))
                      m_drslt(c[n].label, c[n].val, la);
                    if (c[n].mask & xfc_awake) Xf->cstatus = n+1;
#if _HEADLESS
/*--------------------------------------------------
Sleepy Hollow   BEGIN MODS
--------------------------------------------------*/
                    if (Xf->MRMMaster != -1) {
                      if (pMrm[c[n].MWMIndex-1].attach_count>0){
                        Pack.type  = XCNTRL_SET;
                        Pack.dval  = c[n].val;
                        Pack.index = n;
                        Pack.blocked = NON_BLOCKING;
                        Pack.mrm_index = c[n].MWMIndex-1;
                        ermif_send_msg(ERMIF_MAIN,&Pack);
                      }
                    }
/*--------------------------------------------------
Sleepy Hollow   END MODS
--------------------------------------------------*/
#endif
                  }
                  break;
              }

              if (awake) cp_hilite(c, 0, n+1, 1);
              /* In dialog box, move on to the next prompt if the previous */
              /* X-Widget was a prompt and was exited with the Return Key */
              if (move) {
                cp_next(Xf, c, 1);
                if (Xf->current!=n+1 && c[Xf->current-1].wtype==XW_PROMPT) {
                  Mx->key_press = 13;
                  Mx->button_press = 0;
                  goto PROCESSEVENT;
                }
              }
            }
          }

          if (Mx->exposure || Mx->resize) {
            mx_clear_window();
            cp_draw(c, 0, Xf->ncon);
            cp_hilite(c, 0, Xf->current, 0);
          }

        }	/* if (mx_ifevent()) */

        if (!Xf->cstatus && pause) {
#if _HEADLESS
	  if (Xf->MRMMaster != -1) {
	    m_pause(0.001);
          }
	  else {
	    m_pause(0.1);
          }
#else
	  m_pause(0.1);
#endif
        }
        else if (Xf->cstatus > 0 && c[Xf->cstatus-1].callback.p == 0) { 
          cstart = Xf->cstatus;
          Xf->cstatus = 0;
        }

      }	/* while (Xf->cstatus==0 && !*Mcbreak) */
			
/* 18Sep97/jcw Comment out next line per OAF to address delays entering 
   control section
      mx_autorepeat(&autorepeat, 0);
*/
      Mx->no_arrow_move = no_arrow_move;
      if (*Mcbreak) Xf->cstatus = -1;
      if (Xf->cstatus<=0 || (c[Xf->cstatus-1].mask&xfc_blink)) {
        cp_hilite(c, Xf->current, 0, 0);
        Xf->current = -Xf->current;
      }
      if (Xf->configure) mx_unsetbar();
      break;
            
    case L_Draw:
      Mx->resize = FALSE;
      mx_clear_window();
      cp_draw(c, 0, Xf->ncon);
      cp_hilite(c, 0, Xf->current, 0);
      break;

    case L_FocusPanel:
      cp_hilite(c, abs(Xf->current), 0, 0);
      break;

    case L_SavePanel:
      {
        int_4 *setup;

        setup = (int_4 *)Xf->cpsetup.p;
        for (n=i=0; n < Xf->ncon; n++) {
          if (c[n].wtype==XW_NONE) for (j=0; j<3; j++) setup[i++] = -1;
          else {
            setup[i++] = c[n].x;
            setup[i++] = c[n].y;
	    /* the flags below are decoded in the XCALL_PREP routine in
	       the XCALL.FOR host module.  If they change, be sure to update
	       this routine as well. */
            switch (c[n].wtype) {
              case XW_VALUATOR:
		/* Which rows of buttons are visible */
                setup[i++] = c[n].u.dv.buttons;
                break;
              case XW_MENU:
		/* Column width and location of the title */
                 setup[i++] = (c[n].u.mv.iw & 255) + (c[n].u.mv.pad[1] << 8);
                 break;
              case XW_FRAME:
		/* Dimensions of the frame */
                setup[i++] = (c[n].w & 32767) + ((c[n].h & 32767) << 16);
                break;
              default:
                setup[i++] = -1;
            }
          }
        }
      }
      break;

    case L_InitFacilities:
      m_stmalloc(Xf->mcon * L_xwidget, (int_4 *)&Xf->con);
      m_stmalloc(Xf->mcon * 12, (int_4 *)&Xf->cpsetup);
      {
        int_4 *setup;
        setup = (int_4 *)Xf->cpsetup.p;
        c = (XWIDGET *)Xf->con.p;
        for (n=i=0; n < Xf->mcon; n++) {
          c[n].wtype = XW_NONE;
          for (j=0; j<3; j++) setup[i++] = -1;
        }
      }
      Xf->ncon = 0;
      Xf->current = 0;
      Xf->cmenulit = 0;
      Xf->configure = FALSE;
      Xf->chcb.p = 0;
      break;

    case L_CleanExit:
      for (i=0; i<Xf->ncon; i++) {
        if (c[i].wtype != XW_NONE) {
          m_stmfree(c[i].aval_len, c[i].aval.p);
          m_stmfree(c[i].title_len, c[i].title.p);
        }
      }
      m_stmfree(Xf->mcon * L_xwidget, Xf->con.p);
      m_stmfree(Xf->mcon * 12, Xf->cpsetup.p);
      Xf->con.p = 0;
      Xf->cpsetup.p = 0;
      Xf->mcon = 0;
      Xf->ncon = 0;
      break;

  }
}

static void cp_draw (XWIDGET *c, int index, int nelem)

{
  int n;

  for (n=index,nelem+=index; n<nelem; n++) {
    if (c[n].wtype != XW_NONE) {
      if (Mx->resize) (void) mx_widget(&c[n], XW_SETUP);
      if (c[n].mask&xfc_disp) (void) mx_widget(&c[n], XW_DRAW);
    }
  }
  Mx->resize = Mx->exposure = FALSE;
}

static void cp_hilite (XWIDGET *c, int i, int j, int thick)

{
  int m, n;
  m = (thick <= 0) ? 1 : 2;
  if (!G.BW && Mx->xwbg==Mx->xwlo) --m;
  n = 2 * m - 1;
  if (--i>=0) mx_draw_box(-2, c[i].x-m, c[i].y-m, c[i].w+n, c[i].h+n);
  if (--j>=0) mx_draw_box(-2, c[j].x-m, c[j].y-m, c[j].w+n, c[j].h+n);
}

static void cp_next(XFACILITIES *Xf, XWIDGET *c, int dir)

{

  int n, mval;

  n = Xf->current = max(Xf->current, 0);
  if (dir < 0) n = max(1,n) + dir - 1;

  n = (n+Xf->ncon) % Xf->ncon;
  while (n+1!=Xf->current &&
    !((c[n].wtype!=XW_NONE) && (c[n].mask&xfc_edit) && (c[n].mask&xfc_disp))) 
    if ((n+=dir)<0 || n>=Xf->ncon)
      n = (Xf->current==0) ? -1 : (Xf->ncon + n) % Xf->ncon;

  cp_hilite(c, Xf->current, n+1, 0);
  Xf->current = n+1;
	
  /* Handle hiliting and unhiliting menu items due to the shift in focus */
  if (Xf->cmenulit != n+1) {
    if (Xf->cmenulit) {				/* unlite menu items lit in */
      (void)mx_mval(&c[Xf->cmenulit-1], XW_UNHILITE);/* other menus */
      Xf->cmenulit = 0;
    }
    if (n>=0 && c[n].wtype == XW_MENU) { /* single button w/out title */

      if (c[n].title_len<=0 && c[n].u.mv.nitems==1) {	/* focus */
        c[n].u.mv.lit = 1;
        (void)mx_mval(&c[n], XW_UNHILITE);
        c[n].u.mv.lit = 1;
        Xf->cmenulit = n+1;
      }
    }
  }
}
