/* * Baroreflex extensions to eqns.c in the Cardiovascular Simulator. * Timothy Davis, 7/30/89 * Based loosely on the DeBoer beat-to-beat model for * baroreceptor control of heart rate, contractility, * and peripheral resistance, with added control of venous blood volume. * * $Source: /var/tldavis/src/sim/RCS/reflex.c,v $ * $Log: reflex.c,v $ * Revision 2.5 91/02/04 16:43:51 tldavis * Updated arterial pressure setpoint to 98 mm Hg. * * Revision 2.4 90/08/28 14:46:31 tldavis * linted. * * Revision 2.3 90/08/18 18:40:31 tldavis * New location of CVDefs, * also bugifixes to X interface sections, ref. to Interface.c for * dialog boxes. * * Revision 2.2 90/08/10 10:58:08 dot * moved Xaw header files to X11/Xaw for R4 * * Revision 2.1 90/08/07 16:07:26 tldavis * Removed unused variables. * * Revision 2.0 90/08/06 18:02:54 tldavis * Final X11R3 version. * * Revision 1.6 90/05/31 16:27:06 tldavis * Pre-ACIS checkin. * */ #include "CVDefs.h" #include #ifndef NO_X_WINDOWS #include #include #include #include #include #include #include "../nl/NumberLine.h" #include "../main/Interface.h" /* DialogCreate(),PlaceDialog(),KillDialog() */ /*PUBLIC*/ Boolean reflexesOn = 0; #else /*PUBLIC*/ void SimFlush() { ; /*NOOP*/ } typedef char Boolean; #define True 1 #define False 0 /*PUBLIC*/ Boolean reflexesOn = 1; #endif /* The following "signal" variables are used in eqns.c */ /*PUBLIC*/ double sigHR = NHR, sigR = NRA, sigV = NVV0, sigCl = NCLSYS, sigCr = NCRSYS; extern double hr, Ra, Vv0, Clsys, Crsys, Ca; /* from eqns.c */ #define SETPOINT 98 /* Set as close as possible to maintaining homeostasis. */ static Boolean hrActive = True, cActive = True, rActive = True, vActive = True; static double alphaGain = 9, betaGain = 9, paraGain = 9, aSetpoint = SETPOINT; static double alphaTone = 0, betaTone = 0, paraTone = 0; /* baseline */ /***************************************************************************** * Signal history manipulation routines: * save the last 30 seconds in 40 ms increments for * computing time-delayed nervous response signals. *****************************************************************************/ #define Sgran (0.5) /* 500 millisecond granularity in signal history */ #define Slength (60) /* for 60 * 0.5 = 30 seconds of data. */ static double Shist[Slength]; /* queue representing arterial b.p. */ static int top=0; /* head of the queue */ /* Enqueue a blood pressure value */ static void saveS(signal) double signal; { top = (top + Slength - 1) % Slength; /* wraparound modulus arithmetic */ Shist[top] = signal; } static void scaleSignal(scale) double scale; { register int i = 0; for (i = 0; i < Slength; i++) Shist[i] *= scale; } #ifdef NOTDEF static void translateSignal(shift) double shift; { register int i = 0; double max = 18*atan(100000.0); double min = 18*atan(-100000.0); for (i = 0; i < Slength; i++) { Shist[i] += shift; if (Shist[i] > max) Shist[i] = max; if (Shist[i] < min) Shist[i] = min; } } #endif /* Compute weighted sum of past pressures */ static double sumResponse(coeffs, start, end) double coeffs[]; /*Coefficients are in reverse (most recent 1st) order*/ int start, end;/* to optimize in case of short response characteristics */ { double sum = 0.0; int i; for (i = start; i < end; i++) sum += coeffs[i] * Shist[(top + i) % Slength]; /* more modulus math */ return sum; } /* Prepare a list of coeffs to match given triangle ramp parameters. */ static void mkRamp(coeffs, start, peak, end, area) double *coeffs; /* pointer to coeffs buffer*/ double area; /* total sumResponse for unity b.p. signal */ double start, peak, end; /* ramp timing in seconds(to convert to index)*/ { int i; double sum = 0.0; start /= Sgran; peak /= Sgran; end /= Sgran; /* Convert to index */ for (i = start; i < peak; i++) sum += coeffs[i] = (i-((int)start))/(peak-start); for (i = peak; i < end; i++) sum += coeffs[i] = (((int)end) - i)/(end - peak); for (i = start; i < end; i++) coeffs[i] *= area/sum; /* normalizing to required total sum (analogous to area in continuous time) */ } /***************************************************************************** * aCoeff is to be a list of timing coefficients for alpha-sympathetic control. * bCoeff is coefficients for beta-sympathetic control. * pCoeff contains parasympathetic timing information. *****************************************************************************/ static double aCoeff[Slength], bCoeff[Slength], pCoeff[Slength]; static int aStart, aEnd, bStart, bEnd, pStart, pEnd; /*PUBLIC*/ /* used in Event.c */ void setupCoeffs() /* Here we define the shapes of coefficient arrays */ { scaleSignal(0.0); /*zero out everything*/ mkRamp(aCoeff, 2.0, 5.0, 30.0, 1.0); aStart = 2.0 / Sgran; aEnd = 30.0 / Sgran; mkRamp(bCoeff, 2.0, 5.0, 30.0, 1.0); bStart = 2.0 / Sgran; bEnd = 30.0 / Sgran; mkRamp(pCoeff, 0.0, 0.5, 1.0, 1.0); pStart = 0.0 / Sgran; pEnd = 1.0 / Sgran; } /***************************************************************************** * reflex arc definitions: * *****************************************************************************/ /* Reflex arc replacement when reflexes are off */ static void NoReflex() { sigHR = hr; sigCl = Clsys; sigCr = Crsys; sigR = Ra; sigV = Vv0; } /* Reflex arc calculations, performed at ~2 times per beat granularity */ static void Reflexes() { double i, r, v, p; /* DeBoer's lower-case deviation variables */ double alphaResp, betaResp, paraResp, I; static double rho = 0.2 / 0.5088; /* Max Cl deviation / Max i */ static double nu = 750.0 / 0.5088; /* Max V0 deviation / Max i */ /* Calculate current levels of autonomic reflex activity based on past ABP*/ alphaResp = alphaGain * sumResponse(aCoeff, aStart, aEnd) * 0.001; betaResp = betaGain * sumResponse(bCoeff, bStart, bEnd) * 0.001; paraResp = paraGain * sumResponse(pCoeff, pStart, pEnd) * 0.001; /* Interbeat interval (small-signal model) from DeBoer */ i = (hrActive ? betaResp + paraResp : 0.0) - betaTone + paraTone; /* HR determined by both symp. and parasymp. responses */ /* Systolic capacitance linear feedback, scaled to change Clsys and Crsys/3 * by a maximum of 0.2 mmHg/ml. This conforms to Guyton's assertion that * contractility can double with exercise, and stays anove simulation bound * of 0.2 for Clsys. */ p = rho * ((cActive ? betaResp : 0.0) - betaTone)*2; /* Clsys and Crsys/3 deviations */ /* Peripheral resistance (small-signal model) from DeBoer */ r = - ((rActive ? alphaResp : 0.0) - alphaTone)*2 / Ca; /* Venous zero-pressure volume (reflecting venous tone) feedback scaled for * a maximum of 500cc deviation from reference. This comes from Guyton, * who says venous pooling can vary between 600cc and 2600cc from tonus. */ v = nu * ((vActive ? alphaResp : 0.0) - alphaTone)*2; /* Add either feedback signal deviation or pure tonus data * to controlled variables. */ I = 60./hr + i; sigHR = (I < 0.25) ? 60/0.25 : 60./I; /* max HR signal of 240 */ if (sigHR > 250) sigHR = 250.0; if (sigHR < 0) sigHR = 0.0; sigCl = Clsys + p; if (sigCl < 0.2) sigCl = 0.2; sigCr = Crsys + 3*p; if (sigCr < 0.6) sigCr = 0.2; sigR = Ra + r; if (sigR < 0.1) sigR = 0.1; sigV = Vv0+ v; if (sigV < 0.0) sigV = 0.0; } /* The following simply updates the baroreflex on demand for the benefit of * setval() in eqns.c which needs an up-to-date system. */ /*PUBLIC*/ void calcReflexes() { if (reflexesOn) Reflexes(); else NoReflex(); } /* SANODE tickles the s-a node to determine if a new beat should occur. It * does this by integrating a heart rate signal until * average_HR*This_interval >= 1.0. * It also tickles the baroreflex every 40 milliseconds. */ /*PUBLIC*/ void sanode(x, dt) double x[]; double dt; { static double cum_hr = 0.0, cum_t = 0.0; static double cum_t2 , cum_abp = 0.0; /* for 40ms abp average */ static int abp_n = 0, n = 0; cum_t2 += dt; abp_n++; cum_abp += x[1]; if (cum_t2 > Sgran) { /* save signal for the last 40 milliseconds */ double s; /* instantaneous baroreceptor (ascending nerve) signal */ s = 18*atan((cum_abp/abp_n - aSetpoint)/18); /* from DeBoer */ saveS(s); /* enqueue this average pressure */ cum_t2 -= Sgran; abp_n = 0; cum_abp = 0; /*start next interval avging*/ if (reflexesOn) Reflexes(); else NoReflex(); } cum_hr += sigHR; cum_t += dt; n++; /* * Wait until area under the hr signal vs. time curve reaches 1.00, * then start the next beat, as long as we have passed the absolute * refractory period of 1/5 of a beat length since systole. * Setting cum_t to -0.1 gives a 0.1 sec P-R conduction delay. */ if ((cum_t*cum_hr/n >= 60.0) && (x[9] > TBLSEGS * 1.2)) { /* start a new beat */ x[9] = 0.0; /* reset tblc index, which starts a beat. */ cum_hr = 0.0; cum_t = 0.0; n = 0; /* reset summation "IPFM" integral */ btconst(); /* reset simulation constants for next beat */ #ifdef DEBUG if (reflexesOn) printf("signal:%4d, hr:%6.3d, R:%6.3f, Cl:%6.3f, Cr:%6.3f, Vv0:%6.0f\n", (int) Shist[top], (int) sigHR, (float) sigR, (float) sigCl, (float) sigCr, (float) sigV); #endif } } #ifndef NO_X_WINDOWS /************************************************************************** * * User interface to Baroreflex feedback system. * **************************************************************************/ static Widget hrButton, cButton, rButton, vButton, modButton, reflexActiveButton; extern Display *dpy; extern Window root; extern int screen; extern int Stopped; /* from Event.c */ extern void StopSimulator(), ResumeSimulator(); Boolean Paused = False; /*ARGSUSED*/ static void ClearSema(w, client, call) Widget w; caddr_t client, call; { int *sema_ptr = (int *) client; (*sema_ptr)++; if (Paused) ResumeSimulator(); Paused = False; } /*ARGSUSED*/ static void UseDataCallback(w, client, call) Widget w; caddr_t client, call; { Arg args[2]; XEvent ev; while (XCheckWindowEvent(dpy, XtWindow(w), ButtonPressMask, &ev)) ; XtSetArg(args[0],XtNlabel,reflexesOn?"Reflexes are ON":"Reflexes are OFF"); XtSetValues(reflexActiveButton, args, 1); if (reflexesOn) XtSetArg(args[0], XtNsensitive, True); else XtSetArg(args[0], XtNsensitive, False); XtSetValues(hrButton, args, 1); XtSetValues(cButton, args, 1); XtSetValues(rButton, args, 1); XtSetValues(vButton, args, 1); XtSetValues(modButton, args, 1); } /*ARGSUSED*/ static void RestCallback(w, client, call) Widget w; caddr_t client, call; { scaleSignal(0.0); /* zero-out past signal */ UseDataCallback(w, client, call); } static void getReflexToggle(w, client, call) Widget w; caddr_t client, call; { static int modal_sema = 1; XEvent ev; if (!client) { reflexesOn = !reflexesOn; if (reflexesOn) { /* Determine if we want to start from rest state or use current data. */ if (modal_sema) { Widget dialog, rest, usedata; modal_sema--; Paused = !Stopped; if (Paused) StopSimulator(); dialog = DialogCreate(w, "Choose initial reflex response", (char *)0); usedata = XtCreateManagedWidget("Use current data",commandWidgetClass, dialog,(Arg *)NULL, 0); XtAddCallback(usedata, XtNcallback, UseDataCallback, (caddr_t) 0); XtAddCallback(usedata, XtNcallback, ClearSema, (caddr_t) &modal_sema); XtAddCallback(usedata, XtNcallback, KillDialog, (caddr_t) dialog); rest = XtCreateManagedWidget("Reset to rest conditions", commandWidgetClass, dialog, (Arg *)NULL, 0); XtAddCallback(rest, XtNcallback, RestCallback, (caddr_t) 0); XtAddCallback(rest, XtNcallback, ClearSema, (caddr_t) &modal_sema); XtAddCallback(rest, XtNcallback, KillDialog, (caddr_t)dialog); PlaceDialog(dialog, w); } while (XCheckWindowEvent(dpy, XtWindow(w), ButtonPressMask, &ev)) ; } else UseDataCallback(w, client, call); } else UseDataCallback(w, client, call); } static void getLimbToggle(w, client, call) Widget w; caddr_t client, call; { Arg args[3]; Boolean *limb = (Boolean *) client; if (!call) *limb = ! *limb; XtSetArg(args[0],XtNlabel,*limb?"ACTIVE":"inactive"); XtSetValues(w, args, 1); } /*ARGSUSED*/ static void sympCallback(w, client, call) Widget w; caddr_t client, call; { double present, *presentPtr = (double *) client; int done; NumberLineGetValue(w, &present, &done); #ifdef DEBUG printf("Symp. Callback: present = %lf\n", present); #endif *presentPtr = present; } #ifdef NOTDEF /* THIS ISN'T CURRENTLY USED: nonphysiologic all-time setpoint change. /* * setpointChange() callback implements a nonphysiologic setpoint change for * all time, changing the history of the baroreceptor to * pretend the setpoint was this all along. * I consider this nonphysiologic and thus unintuitive. */ /*ARGSUSED*/ static void setpointChange(w, client, call) Widget w; caddr_t client, call; { static double previous = SETPOINT; double present; int done; NumberLineGetValue(w, &present, &done); /* Change the all signal from the baroreceptor to center on the NEW setpoint */ translateSignal(previous - present); previous = present; } #endif /*ARGSUSED*/ static void destroyNotify(w, client, call) Widget w; caddr_t client, call; { *((Boolean *)client) = False; } /*ARGSUSED*/ static void dummyHandler(w, client, event) Widget w; caddr_t client; XEvent *event; { ; /*nothing*/ } /*ARGSUSED*/ static void modReflexCallback(w, client, call) Widget w; caddr_t client, call; { Arg args[20]; int i, j; static Widget shell, form, titleLabel, alphaNl, betaNl, paraNl, setpointNl, atNl, btNl, ptNl; static double smin = 0, pmin = 0, smax = 20, pmax = 20, sdef = 9, pdef = 9; static double tmin = -1, tmax = 1, tdef = 0; static double amin = 0, amax = 200, adef = 90; static Boolean Exists = False; if (Exists) return; else Exists = True; i=0; XtSetArg(args[i], XtNallowShellResize, True);i++; XtSetArg(args[i], XtNiconName, "Baroreceptor Reflex Parameters");i++; #ifdef XAW_BC shell = XtCreateApplicationShell("baroreceptor_parameters", topLevelShellWidgetClass, args, i); #else shell = XtAppCreateShell(NULL,"CVsim", topLevelShellWidgetClass,dpy,args,i); #endif XtAddCallback(shell, XtNdestroyCallback, destroyNotify, (caddr_t)&Exists); XtAddEventHandler(shell, ButtonPressMask | ButtonReleaseMask, False, dummyHandler, (caddr_t)0); form = XtCreateManagedWidget("Baroreceptor Reflex", formWidgetClass, shell, (Arg *)0, 0); i=0; XtSetArg(args[i], XtNvertDistance, 4);i++; XtSetArg(args[i], XtNresizable, True);i++; j = i; XtSetArg(args[i], XtNborderWidth, 0);i++; titleLabel = XtCreateManagedWidget("BARORECEPTOR REFLEX PARAMETERS", labelWidgetClass, form, args, i); XtSetArg(args[j], XtNwidth, 200);j++; i=j; XtSetArg(args[i], XtNfromVert, titleLabel);i++; XtSetArg(args[i], XtNlabel, "ABP Setpoint (mmHg)");i++; XtSetArg(args[i], XtNminimum, &amin);i++; XtSetArg(args[i], XtNmaximum, &amax);i++; XtSetArg(args[i], XtNpresent, &aSetpoint);i++; XtSetArg(args[i], XtNdefault, &adef);i++; XtSetArg(args[i], XtNprevious, &aSetpoint);i++; setpointNl = XtCreateManagedWidget("numberLine", numberLineWidgetClass, form, args, i); XtAddCallback(setpointNl, XtNcallback, sympCallback,(caddr_t) &aSetpoint); #ifdef NOTDEF /* Nonphysiologic "total" setpoint changes. */ XtAddCallback(setpointNl, XtNcallback, setpointChange, (caddr_t) &aSetpoint); #endif /* Left side */ i=j; XtSetArg(args[i], XtNfromVert, setpointNl);i++; XtSetArg(args[i], XtNlabel, "Periph. Sympathetic Tone");i++; XtSetArg(args[i], XtNminimum, &tmin);i++; XtSetArg(args[i], XtNmaximum, &tmax);i++; XtSetArg(args[i], XtNpresent, &alphaTone);i++; XtSetArg(args[i], XtNdefault, &tdef);i++; XtSetArg(args[i], XtNprevious, &alphaTone);i++; atNl = XtCreateManagedWidget("numberLine", numberLineWidgetClass, form, args, i); XtAddCallback(atNl, XtNcallback, sympCallback,(caddr_t) &alphaTone); i=j; XtSetArg(args[i], XtNfromVert, atNl);i++; XtSetArg(args[i], XtNlabel, "Heart Sympathetic Tone");i++; XtSetArg(args[i], XtNminimum, &tmin);i++; XtSetArg(args[i], XtNmaximum, &tmax);i++; XtSetArg(args[i], XtNpresent, &betaTone);i++; XtSetArg(args[i], XtNdefault, &tdef);i++; XtSetArg(args[i], XtNprevious, &betaTone);i++; btNl = XtCreateManagedWidget("numberLine", numberLineWidgetClass, form, args, i); XtAddCallback(btNl, XtNcallback, sympCallback,(caddr_t) &betaTone); i=j; XtSetArg(args[i], XtNfromVert, btNl);i++; XtSetArg(args[i], XtNlabel, "Parasympathetic Tone");i++; XtSetArg(args[i], XtNminimum, &tmin);i++; XtSetArg(args[i], XtNmaximum, &tmax);i++; XtSetArg(args[i], XtNpresent, ¶Tone);i++; XtSetArg(args[i], XtNdefault, &tdef);i++; XtSetArg(args[i], XtNprevious, ¶Tone);i++; ptNl = XtCreateManagedWidget("numberLine", numberLineWidgetClass, form, args, i); XtAddCallback(ptNl, XtNcallback, sympCallback,(caddr_t) ¶Tone); /* right side */ i=j; XtSetArg(args[i], XtNfromVert, setpointNl);i++; XtSetArg(args[i], XtNfromHoriz, setpointNl);i++; XtSetArg(args[i], XtNlabel, "Periph. Sympathetic Gain");i++; XtSetArg(args[i], XtNminimum, &smin);i++; XtSetArg(args[i], XtNmaximum, &smax);i++; XtSetArg(args[i], XtNpresent, &alphaGain);i++; XtSetArg(args[i], XtNdefault, &sdef);i++; XtSetArg(args[i], XtNprevious, &alphaGain);i++; alphaNl = XtCreateManagedWidget("numberLine", numberLineWidgetClass, form, args, i); XtAddCallback(alphaNl, XtNcallback, sympCallback,(caddr_t) &alphaGain); i=j; XtSetArg(args[i], XtNfromVert, alphaNl);i++; XtSetArg(args[i], XtNfromHoriz, setpointNl);i++; XtSetArg(args[i], XtNlabel, "Heart Sympathetic Gain");i++; XtSetArg(args[i], XtNminimum, &smin);i++; XtSetArg(args[i], XtNmaximum, &smax);i++; XtSetArg(args[i], XtNpresent, &betaGain);i++; XtSetArg(args[i], XtNdefault, &sdef);i++; XtSetArg(args[i], XtNprevious, &betaGain);i++; betaNl = XtCreateManagedWidget("numberLine", numberLineWidgetClass, form, args, i); XtAddCallback(betaNl, XtNcallback, sympCallback,(caddr_t) &betaGain); i=j; XtSetArg(args[i], XtNfromVert, betaNl);i++; XtSetArg(args[i], XtNlabel, "Parasympathetic Gain");i++; XtSetArg(args[i], XtNfromHoriz, setpointNl);i++; XtSetArg(args[i], XtNminimum, &pmin);i++; XtSetArg(args[i], XtNmaximum, &pmax);i++; XtSetArg(args[i], XtNpresent, ¶Gain);i++; XtSetArg(args[i], XtNdefault, &pdef);i++; XtSetArg(args[i], XtNprevious, ¶Gain);i++; paraNl = XtCreateManagedWidget("numberLine", numberLineWidgetClass, form, args, i); XtAddCallback(paraNl, XtNcallback, sympCallback,(caddr_t) ¶Gain); XtRealizeWidget(shell); XtPopup(shell, XtGrabNone); XtMapWidget(shell); } /*PUBLIC*/ void ReflexesOff() { if (reflexActiveButton) getReflexToggle((Widget)reflexActiveButton,(caddr_t)!reflexesOn, (caddr_t)0); } /*ARGSUSED*/ /*PUBLIC*/ void ReflexButton(widget, client, call) Widget widget; caddr_t client, call; { static Widget titleLabel, hrLabel, cLabel, rLabel, vLabel, form, shell; Arg args[20]; int i, j; static Boolean Exists = False; if (Exists) return; else Exists = True; i=0; XtSetArg(args[i], XtNallowShellResize, True);i++; XtSetArg(args[i], XtNiconName, "Baroreceptor Reflex Control");i++; #ifdef XAW_BC shell = XtCreateApplicationShell("baroreceptor_control" topLevelShellWidgetClass, args, i); #else shell = XtAppCreateShell(NULL,"CVsim",topLevelShellWidgetClass,dpy,args,i); #endif XtAddCallback(shell, XtNdestroyCallback, destroyNotify, (caddr_t)&Exists); XtAddEventHandler(shell, ButtonPressMask | ButtonReleaseMask, False, dummyHandler, (caddr_t)0); form = XtCreateManagedWidget("Baroreceptor Reflex", formWidgetClass, shell, (Arg *)0, 0); i=0; XtSetArg(args[i], XtNtop, XtChainTop);i++; XtSetArg(args[i], XtNbottom, XtChainTop);i++; XtSetArg(args[i], XtNleft, XtChainLeft);i++; XtSetArg(args[i], XtNright, XtChainLeft);i++; XtSetArg(args[i], XtNvertDistance, 8);i++; XtSetArg(args[i], XtNresizable, True);i++; j = i; XtSetArg(args[i], XtNborderWidth, 0);i++; titleLabel = XtCreateManagedWidget("BARORECEPTOR REFLEX CONTROL", labelWidgetClass, form, args, i); i=j; XtSetArg(args[i], XtNfromHoriz, titleLabel); i++; XtSetArg(args[i], XtNborderWidth, 3); i++; reflexActiveButton = XtCreateManagedWidget("ReflexesActiveButton", commandWidgetClass, form, args, i); XtAddCallback(reflexActiveButton,XtNcallback, getReflexToggle, (caddr_t)0); i=j; XtSetArg(args[i], XtNfromVert, titleLabel);i++; XtSetArg(args[i], XtNborderWidth, 0);i++; hrLabel = XtCreateManagedWidget("Heart Rate feedback:", labelWidgetClass, form, args, i); i=j; XtSetArg(args[i], XtNfromVert, titleLabel);i++; XtSetArg(args[i], XtNfromHoriz, titleLabel);i++; XtSetArg(args[i], XtNborderWidth, 3); hrButton = XtCreateManagedWidget("hrButton", commandWidgetClass, form, args, i); XtAddCallback(hrButton, XtNcallback, getLimbToggle, (caddr_t) &hrActive); i=j; XtSetArg(args[i], XtNfromVert, hrLabel);i++; XtSetArg(args[i], XtNborderWidth, 0);i++; cLabel = XtCreateManagedWidget("Contractility feedback:", labelWidgetClass, form, args, i); i=j; XtSetArg(args[i], XtNfromVert, hrLabel);i++; XtSetArg(args[i], XtNfromHoriz, titleLabel);i++; XtSetArg(args[i], XtNborderWidth, 3); cButton = XtCreateManagedWidget("cButton",commandWidgetClass,form,args, i); XtAddCallback(cButton, XtNcallback, getLimbToggle, (caddr_t) &cActive); i=j; XtSetArg(args[i], XtNfromVert, cLabel);i++; XtSetArg(args[i], XtNborderWidth, 0);i++; rLabel=XtCreateManagedWidget("Art. Resistance feedback:",labelWidgetClass, form, args, i); i=j; XtSetArg(args[i], XtNfromVert, cLabel);i++; XtSetArg(args[i], XtNfromHoriz, rLabel);i++; XtSetArg(args[i], XtNborderWidth, 3); rButton = XtCreateManagedWidget("rButton",commandWidgetClass,form,args,i); XtAddCallback(rButton, XtNcallback, getLimbToggle, (caddr_t) &rActive); i=j; XtSetArg(args[i], XtNfromVert, rLabel);i++; XtSetArg(args[i], XtNborderWidth, 0);i++; vLabel = XtCreateManagedWidget("Venous tone feedback:", labelWidgetClass, form, args, i); i=j; XtSetArg(args[i], XtNfromVert, rLabel);i++; XtSetArg(args[i], XtNfromHoriz, rLabel);i++; XtSetArg(args[i], XtNborderWidth, 3); vButton = XtCreateManagedWidget("vButton",commandWidgetClass,form,args,i); XtAddCallback(vButton, XtNcallback, getLimbToggle, (caddr_t) &vActive); i=j; XtSetArg(args[i], XtNfromVert, vLabel);i++; XtSetArg(args[i], XtNborderWidth, 3); modButton = XtCreateManagedWidget("Modify Reflex Parameters", commandWidgetClass, form, args, i); XtAddCallback(modButton, XtNcallback, modReflexCallback, (caddr_t)0); XtRealizeWidget(shell); XtPopup(shell, XtGrabNone); XtMapWidget(shell); getReflexToggle((Widget)reflexActiveButton, (caddr_t)1, (caddr_t)0); getLimbToggle(hrButton, (caddr_t)&hrActive, (caddr_t)1); getLimbToggle(cButton, (caddr_t)&cActive, (caddr_t)1); getLimbToggle(rButton, (caddr_t)&rActive, (caddr_t)1); getLimbToggle(vButton, (caddr_t)&vActive, (caddr_t)1); } #endif /*** end of Reflex Interface *********************************************/