home *** CD-ROM | disk | FTP | other *** search
/ AMIGA PD 1 / AMIGA-PD-1.iso / Meeting_Pearls_II / html / sw / nbsd / FuzzyPendel / xpendel.c < prev   
C/C++ Source or Header  |  1994-07-02  |  44KB  |  1,652 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <signal.h>
  5. #include <math.h>
  6. #include <Xm/Xm.h>
  7. #include <Xm/Form.h>
  8. #include <Xm/PushB.h>
  9. #include <Xm/PushBG.h>
  10. #include <Xm/Separator.h>
  11. #include <Xm/CascadeB.h>
  12. #include <Xm/MessageB.h>
  13. #include <Xm/DialogS.h>
  14. #include <Xm/SeparatoG.h>
  15. #include <Xm/PanedW.h>
  16. #include <Xm/Text.h>
  17. #include <Xm/TextF.h>
  18. #include <Xm/RowColumn.h>
  19. #include <Xm/Frame.h>
  20. #include <Xm/Label.h>
  21. #include <Xm/MainW.h>
  22. #include <Xm/ArrowB.h>
  23. #include <X11/Shell.h>
  24. #include <assert.h>
  25.  
  26. #define PI M_PI
  27. #ifndef SQR
  28. #define SQR(x)      ((x)*(x))
  29. #endif /* SQR */
  30. #ifndef MAX
  31. #define MAX(a,b)    ((a)>(b)?(a):(b))
  32. #endif /* MAX */
  33. #ifndef MIN
  34. #define MIN(a,b)    ((a)<(b)?(a):(b))
  35. #endif /* MIN */
  36.  
  37.  
  38. /*
  39.  * Konstante
  40.  */
  41. #define g                  9.81
  42.  
  43. #define m                  1.0
  44. #define l                  1.0
  45. #define deltaT             0.005
  46. #define ALPHA0            55.0*(PI/180.0)
  47. #define ALPHA_DOT0         1.5
  48. #define A0                 5.0
  49. #define A1             50000.0
  50.  
  51. #define X_SIZE           900
  52. #define Y_SIZE           100
  53. #define X_SIZE_SD        280          /* Breite SetDefaults-Dialog */
  54. #define Y_SIZE_SD        183          /* Hoehe SetDefaults-Dialog */
  55. #define X_SIZE_AB        280          /* Breite About-"Bitte Warten" */
  56. #define Y_SIZE_AB        83          /* Hoehe About-"Bitte Warten" */
  57. #define Xscale            90.0        /* for W_core_pendel */
  58. #define Yscale            90.0        /* for W_core_pendel */
  59. #define PERIOD_SOME        4          /* Dauer zwischen Pendel-Updates */
  60. #define ANGLE_DELTA_X      0.5
  61.  
  62. /*
  63.  * Diverses anderes
  64.  */
  65. #define PENDEL_FRACTION 20
  66.  
  67. #define FONT_NORMAL       "font_normal"
  68. #define FONT_NORMAL_NAME  "fixed"
  69. #define FONT_BIG          "font_big"
  70. #define FONT_BIG_NAME     "-*-helvetica-*-r-*--*-240-*-*-*-*-iso8859-1"
  71.  
  72.  
  73. /*
  74.  * Variablen fuer balance
  75.  */
  76. #define NB               0
  77. #define NM               1
  78. #define NS               2
  79. #define ZE               3
  80. #define PS               4 
  81. #define PM               5
  82. #define PB               6
  83. #define NRANGES          7            /* Werte von NB, NM, ... */
  84.  
  85. #define ALPHA            range[0].value
  86. #define ALPHA_DOT        range[1].value
  87. #define A                range[2].value
  88. #define ALPHA_RANGE      0
  89. #define ALPHA_DOT_RANGE  1
  90. #define A_RANGE          2
  91.  
  92. #define Bumper_alphaDot  0.5
  93. #define Bumper_alpha     10.0*(PI/180.0)
  94.  
  95. typedef struct _Bound {
  96.     double lower;
  97.     double upper;
  98. } Bound;
  99.  
  100. typedef struct _Rule {
  101.     int alpha;                       /* wenn alpha == ... und */
  102.     int alphaDot;                    /* alphaDot == ... dann */
  103.     int a;                           /* a = ... */
  104. } Rule;
  105.  
  106. Rule rule[]={            /* wenn ... und ... dann ... */
  107.     { PM, ZE, PM },
  108.     { PS, PS, PM },
  109.     { PS, NS, ZE },
  110.     { NM, ZE, NM },
  111.     { NS, NS, NM },
  112.     { NS, PS, ZE },
  113.     { ZE, ZE, ZE },
  114. };
  115. #define NRULES           (sizeof(rule)/sizeof(Rule))
  116.  
  117. Bound alpha_mbounds = { -30.0, 210.0 };
  118. Bound alpha_bound[NRANGES] = {
  119.     { -30.0,  30.0 },           /* /\             */
  120.     {   0.0,  60.0 },           /*   /\           */
  121.     {  30.0,  90.0 },           /*     /\         */
  122.     {  60.0, 120.0 },           /*       /\       */
  123.     {  90.0, 150.0 },           /*         /\     */
  124.     { 120.0, 180.0 },           /*           /\   */
  125.     { 150.0, 210.0 }            /*             /\ */
  126. };
  127. Bound alphaDot_mbounds = { -5.0, 5.0 };
  128. Bound alphaDot_bound[NRANGES] = {
  129.     { -5.0, -1.0 },             /* /\             */
  130.     { -3.0, -1.0 },             /*   /\           */
  131.     { -2.0,  1.0 },             /*     /\         */
  132.     { -0.5,  0.5 },             /*       /\       */
  133.     { -1.0,  2.0 },             /*         /\     */
  134.     {  1.0,  3.0 },             /*           /\   */
  135.     {  1.0,  5.0 },             /*             /\ */
  136. };
  137. Bound a_mbounds = { -7.0, 7.0 };
  138. Bound a_bound[NRANGES] = {
  139.     { -7.0, -5.0 },             /* /\             */
  140.     { -5.0, -3.0 },             /*   /\           */
  141.     { -3.0, -1.0 },             /*     /\         */
  142.     { -1.0,  1.0 },             /*       /\       */
  143.     {  1.0,  3.0 },             /*         /\     */
  144.     {  3.0,  5.0 },             /*           /\   */
  145.     {  5.0,  7.0 },             /*             /\ */
  146. };
  147. double Fa;
  148. double Fg;
  149. double xpos,oldxpos;
  150. int angle_tick;
  151. double angle_xpos, angle_oldxpos;
  152. double angle_ypos, angle_oldypos;
  153. double alpha0,alphaDot0;
  154. double a0;                           /* max. Beschleuningung */
  155. char *range_name[7] = { "NB","NM","NS","ZE","PS","PM","PB" };
  156.  
  157.  
  158. /*
  159.  *  Variablen fuer X/Motif
  160.  */
  161. typedef struct _Value {
  162.     Widget     W_form;
  163.     Widget       W_label;
  164.     Widget       W_value;
  165.     double         value;
  166. } Value;
  167.  
  168. typedef struct _Range {
  169.     Widget W_frame;
  170.     Widget   W_box;         /* rowcolumn */
  171.     Widget     W_title;
  172.     char*        title;
  173.     Widget     W_sep1;
  174.     Value      value[NRANGES];
  175.     Widget     W_sep2;
  176.     Widget     W_core_values;
  177.     GC         gc_core_values;
  178.     Widget     W_exact;
  179.     double       exact;
  180.     double       oldexact;
  181. } Range;
  182.  
  183. Widget W_toplevel;
  184. Widget   W_main;
  185. Widget     W_rc_outer;
  186. Widget       W_menubar;
  187. Widget         W_file_menu;
  188. Widget           W_file_foobar;
  189. Widget             W_reset_menuitem;
  190. Widget             W_setdefaults_menuitem;
  191. Widget               W_sd_dialog; 
  192. Widget                 W_sd_rc;
  193. Widget                   W_sd_title_form;
  194. Widget                     W_sd_title;
  195. Widget                   W_sd_sep1;
  196. Widget                   W_sd_control_rc;
  197. Widget                     W_sd_alpha0_form;
  198. Widget                       W_sd_alpha0_label;
  199. Widget                       W_sd_alpha0_text;
  200. Widget                         W_sd_alpha0_Error;
  201. Widget                     W_sd_alphaDot0_form;
  202. Widget                       W_sd_alphaDot0_label;
  203. Widget                       W_sd_alphaDot0_text;
  204. Widget                     W_sd_a0_form;
  205. Widget                       W_sd_a0_label;
  206. Widget                       W_sd_a0_text;
  207. Widget                         W_sd_a0_Error;
  208. Widget                   W_sd_sep2; 
  209. Widget                   W_sd_action_form;
  210. Widget                     W_sd_ok;
  211. Widget                     W_sd_cancel;
  212. Widget             W_about_menuitem;
  213. Widget               W_ab_dialog;
  214. Widget                 W_ab_frame;
  215. Widget                   W_ab_rc;
  216. Widget                     W_ab_form;
  217. Widget                       W_ab_pleasewait;
  218. Widget             W_sep_menuitem;
  219. Widget             W_quit_menuitem;
  220. Widget       W_title_form;
  221. Widget         W_title;
  222. Widget       W_sep1;
  223. Widget       W_rc_main;
  224. Widget         W_form_pendel;
  225. Widget           W_push_left;
  226. Widget           W_core_pendel;
  227. Widget           W_push_right;
  228. Widget         W_core_angle;
  229. Widget         W_form_ranges;
  230. Range            range[3];
  231. Widget         W_form_exacts;
  232. Widget       W_sep2;
  233. Widget       W_form_bottom;
  234. Widget         W_startstop;
  235. Widget         W_step;
  236. Widget         W_quit;
  237.  
  238. XtAppContext app_context;
  239.  
  240. XFontStruct *font;
  241. XmFontList fontlist;
  242.  
  243. Colormap cmap;
  244. GC gc_core_pendel;
  245. GC gc_core_angle;
  246. unsigned long black, white;
  247. XColor     col_red;
  248. XColor     col_yellow;
  249.  
  250.  
  251. /*
  252.  * Prototypen
  253.  */
  254. double balance(double alpha, double alphaDot);
  255. void update_widgets(int all);
  256. void update_values(void);
  257. void periodicTO(Widget w);
  258. void stepCB(Widget w, XtPointer client_data, XtPointer call_data);
  259. void quitCB(Widget w, XtPointer client_data, XtPointer call_data);
  260. void startstopCB(Widget w, XtPointer client_data, XtPointer call_data);
  261. void pushCB(Widget w, XtPointer client_data, XtPointer call_data);
  262. void aboutCB(Widget w, XtPointer client_data, XtPointer call_data);
  263. void aboutAlarm(int sig);
  264. void setdefaultsCB(Widget w, XtPointer client_data, XtPointer call_data);
  265. void sd_okCB(Widget w, XtPointer client_data, XtPointer call_data);
  266. void sd_cancelCB(Widget w, XtPointer client_data, XtPointer call_data);
  267. void resetCB(Widget w, XtPointer client_data, XtPointer call_data);
  268. void init(int argc, char *argv[]);
  269.  
  270. /*************************************************************************/
  271. double balance(double alpha, double alphaDot)
  272. {
  273.     double max,mid;
  274.     int i;
  275.  
  276.     range[ALPHA_RANGE].exact     = alpha;
  277.     range[ALPHA_RANGE].oldexact  = alpha;
  278.     range[ALPHA_DOT_RANGE].exact = alphaDot;
  279.     
  280.     /* Gewichte von alpha ausrechnen */
  281.     for(i=0;i<NRANGES;i++){
  282.     if((alpha_bound[i].upper > alpha) && (alpha > alpha_bound[i].lower)){
  283.         mid = (alpha_bound[i].upper+alpha_bound[i].lower)/2.0;
  284.         if(alpha>mid){
  285.         /* linke Haelfte */
  286.         ALPHA[i].value
  287.           = 1.0-(alpha-mid)/(alpha_bound[i].upper-mid);
  288.         }else{
  289.         /* rechte Haelfte */
  290.         ALPHA[i].value
  291.           = (alpha-alpha_bound[i].lower)/(mid-alpha_bound[i].lower);
  292.         }
  293.     }else{
  294.         ALPHA[i].value = 0.0;
  295.     }
  296.     }
  297.  
  298.     /* Gewichte von alphaDot ausrechnen */
  299.     for(i=0;i<NRANGES;i++){
  300.     if((alphaDot_bound[i].upper > alphaDot) &&
  301.        (alphaDot > alphaDot_bound[i].lower)){
  302.         mid = (alphaDot_bound[i].upper+alphaDot_bound[i].lower)/2.0; 
  303.         if(alphaDot>mid){
  304.         /* rechte Haelfte */
  305.         ALPHA_DOT[i].value
  306.           = 1.0-(alphaDot-mid)/(alphaDot_bound[i].upper-mid);
  307.         }else{
  308.         /* linke Haelfte */
  309.         ALPHA_DOT[i].value
  310.           = (alphaDot-alphaDot_bound[i].lower)
  311.             /(mid-alphaDot_bound[i].lower);
  312.         }
  313.     }else{
  314.         ALPHA_DOT[i].value = 0.0;
  315.     }
  316.     }
  317.  
  318.     /* Regeln anwenden */
  319.     for(i=0;i<NRULES;i++){
  320.     A[i].value = 0.0;
  321.     }
  322.     for(i=0;i<NRULES;i++){
  323.     A[rule[i].a].value =
  324.       MAX(A[rule[i].a].value,
  325.           MIN(ALPHA[rule[i].alpha].value,
  326.           ALPHA_DOT[rule[i].alphaDot].value));
  327.     }
  328.  
  329.     /* Mittelwert der A's berechnen */
  330.     max=0.0;
  331.     for(i=0;i<NRANGES;i++){
  332.     max = max + (i-(NRANGES/2))*A[i].value;
  333.     }
  334.  
  335.     range[A_RANGE].exact = -max;
  336.  
  337.     return -max;
  338. }
  339.  
  340. /*************************************************************************/
  341. void periodicTO(Widget w)
  342. {
  343.     if(!XtIsSensitive(W_step)){
  344.     update_values();
  345.     update_widgets(0);
  346.     XtAppAddTimeOut(app_context,PERIOD_SOME,(XtTimerCallbackProc)periodicTO,
  347.             (XtPointer)0);
  348.     }
  349. }
  350.  
  351. /*************************************************************************/
  352. void stepCB(Widget w, XtPointer client_data, XtPointer call_data)
  353. {
  354.     update_values();
  355.     update_widgets(1);
  356. }
  357.  
  358. /*************************************************************************/
  359. void setdefaultsCB(Widget widget, XtPointer client_data, XtPointer call_data)
  360. {
  361.     char str[256];
  362.     XmString xstr;
  363.     Position x,y;
  364.     Dimension w,h;
  365.  
  366.     if(!W_sd_dialog){
  367.     XtVaGetValues(W_main,
  368.               XmNwidth,&w,
  369.               XmNheight,&h,
  370.               XmNx,&x,
  371.               XmNy,&y,
  372.               NULL);
  373.     
  374.     W_sd_dialog
  375.       = XtVaCreateManagedWidget("sd_dialog",
  376.                     xmDialogShellWidgetClass,
  377.                     W_toplevel,
  378.                     XmNx,x+(w-X_SIZE_SD)/2,
  379.                     XmNy,y+(h-Y_SIZE_SD)/2,
  380.                     NULL);
  381.  
  382.     W_sd_rc
  383.       = XtVaCreateManagedWidget("sd_rc",
  384.                     xmRowColumnWidgetClass,
  385.                     W_sd_dialog,
  386.                     XmNwidth, X_SIZE_SD,
  387.                     XmNheight, Y_SIZE_SD,
  388.                     NULL);
  389.  
  390.     {
  391.         /* Titel */
  392.         W_sd_title_form
  393.           = XtVaCreateManagedWidget("sd_title_form",
  394.                     xmFormWidgetClass,
  395.                     W_sd_rc,
  396.                     XmNfractionBase,1,
  397.                     NULL);
  398.  
  399.         xstr=XmStringCreate("Set Defaults",FONT_BIG);
  400.         W_sd_title
  401.           = XtVaCreateManagedWidget("sd_title",
  402.                     xmLabelWidgetClass,
  403.                     W_sd_title_form,
  404.                     XmNlabelString,xstr,
  405.                     XmNfontList,fontlist,
  406.                     XmNalignment,XmALIGNMENT_CENTER,
  407.                     XmNleftAttachment,XmATTACH_POSITION,
  408.                     XmNleftPosition,0,
  409.                     XmNrightAttachment,XmATTACH_POSITION,
  410.                     XmNrightPosition,1,
  411.                     NULL);
  412.         XmStringFree(xstr);
  413.     }
  414.     W_sd_sep1
  415.       = XtVaCreateManagedWidget("sd_sep1",
  416.                     xmSeparatorWidgetClass,
  417.                     W_sd_rc,
  418.                     NULL);
  419.     {
  420.         /* Control */
  421.        
  422.         W_sd_control_rc
  423.           = XtVaCreateManagedWidget("sd_control_rc",
  424.                     xmRowColumnWidgetClass,
  425.                     W_sd_rc,
  426.                     XmNfontList,fontlist,
  427.                     NULL);
  428.  
  429.         {
  430.         /* alpha0 */
  431.         W_sd_alpha0_form
  432.           = XtVaCreateManagedWidget("sd_alpha0_form",
  433.                         xmFormWidgetClass,
  434.                         W_sd_control_rc,
  435.                         NULL);
  436.         
  437.         xstr=XmStringCreate("Alpha0: ",FONT_NORMAL);
  438.         W_sd_alpha0_label
  439.           = XtVaCreateManagedWidget("sd_alpha0_label",
  440.                         xmLabelWidgetClass,
  441.                         W_sd_alpha0_form,
  442.                         XmNlabelString,xstr,
  443.                         XmNfontList,fontlist,
  444.                         XmNalignment,XmALIGNMENT_BEGINNING,
  445.                         XmNleftAttachment,XmATTACH_FORM,
  446.                         XmNtopAttachment,XmATTACH_FORM,
  447.                         XmNbottomAttachment,XmATTACH_FORM,
  448.                         NULL);
  449.         XmStringFree(xstr);
  450.         
  451.         sprintf(str,"%6.2f",alpha0/PI*180.0);
  452.         W_sd_alpha0_text
  453.           = XtVaCreateManagedWidget("sd_alpha0_text",
  454.                         xmTextFieldWidgetClass,
  455.                         W_sd_alpha0_form,
  456.                         XmNvalue,str,
  457.                         XmNfontList,fontlist,
  458.                         XmNalignment,XmALIGNMENT_END,
  459.                         XmNleftAttachment,XmATTACH_WIDGET,
  460.                         XmNleftWidget,W_sd_alpha0_label,
  461.                         XmNrightAttachment,XmATTACH_FORM,
  462.                         NULL);
  463.         }
  464.         {
  465.         /* alphaDot0 */
  466.         W_sd_alphaDot0_form
  467.           = XtVaCreateManagedWidget("sd_alphaDot0_form",
  468.                         xmFormWidgetClass,
  469.                         W_sd_control_rc,
  470.                         NULL);
  471.         
  472.         xstr=XmStringCreate("AlphaDot0: ",FONT_NORMAL);
  473.         W_sd_alphaDot0_label
  474.           = XtVaCreateManagedWidget("sd_alphaDot0_label",
  475.                         xmLabelWidgetClass,
  476.                         W_sd_alphaDot0_form,
  477.                         XmNlabelString,xstr,
  478.                         XmNfontList,fontlist,
  479.                         XmNalignment,XmALIGNMENT_BEGINNING,
  480.                         XmNleftAttachment,XmATTACH_FORM,
  481.                         XmNtopAttachment,XmATTACH_FORM,
  482.                         XmNbottomAttachment,XmATTACH_FORM,
  483.                         NULL);
  484.         XmStringFree(xstr);
  485.         
  486.         sprintf(str,"%6.2f",alphaDot0);
  487.         W_sd_alphaDot0_text
  488.           = XtVaCreateManagedWidget("sd_alphaDot0_text",
  489.                         xmTextWidgetClass,
  490.                         W_sd_alphaDot0_form,
  491.                         XmNvalue,str,
  492.                         XmNfontList,fontlist,
  493.                         XmNalignment,XmALIGNMENT_END,
  494.                         XmNleftAttachment,XmATTACH_WIDGET,
  495.                         XmNleftWidget,W_sd_alphaDot0_label,
  496.                         XmNrightAttachment,XmATTACH_FORM,
  497.                         NULL);
  498.         }
  499.         {
  500.         /* a0 */
  501.         W_sd_a0_form
  502.           = XtVaCreateManagedWidget("sd_a0_form",
  503.                         xmFormWidgetClass,
  504.                         W_sd_control_rc,
  505.                         NULL);
  506.         
  507.         xstr=XmStringCreate("a0: ",FONT_NORMAL);
  508.         W_sd_a0_label
  509.           = XtVaCreateManagedWidget("sd_a0_label",
  510.                         xmLabelWidgetClass,
  511.                         W_sd_a0_form,
  512.                         XmNlabelString,xstr,
  513.                         XmNfontList,fontlist,
  514.                         XmNalignment,XmALIGNMENT_BEGINNING,
  515.                         XmNleftAttachment,XmATTACH_FORM,
  516.                         XmNtopAttachment,XmATTACH_FORM,
  517.                         XmNbottomAttachment,XmATTACH_FORM,
  518.                         NULL);
  519.         XmStringFree(xstr);
  520.         
  521.         sprintf(str,"%6.2f",a0);
  522.         W_sd_a0_text
  523.           = XtVaCreateManagedWidget("sd_a0_text",
  524.                         xmTextWidgetClass,
  525.                         W_sd_a0_form,
  526.                         XmNvalue,str,
  527.                         XmNfontList,fontlist,
  528.                         XmNalignment,XmALIGNMENT_END,
  529.                         XmNleftAttachment,XmATTACH_WIDGET,
  530.                         XmNleftWidget,W_sd_a0_label,
  531.                         XmNrightAttachment,XmATTACH_FORM,
  532.                         NULL);
  533.         }
  534.     }
  535.     W_sd_sep2
  536.       = XtVaCreateManagedWidget("sd_sep2",
  537.                     xmSeparatorWidgetClass,
  538.                     W_sd_rc,
  539.                     NULL);
  540.     {
  541.         /* Action */
  542.         W_sd_action_form
  543.           = XtVaCreateManagedWidget("sd_action_form",
  544.                     xmFormWidgetClass,
  545.                     W_sd_rc,
  546.                     XmNfractionBase,5,
  547.                     NULL);
  548.  
  549.         xstr=XmStringCreate("OK",FONT_NORMAL);
  550.         W_sd_ok
  551.           = XtVaCreateManagedWidget("sd_ok",
  552.                     xmPushButtonWidgetClass,
  553.                     W_sd_action_form,
  554.                     XmNfontList,fontlist,
  555.                     XmNlabelString,xstr,
  556.                     XmNleftAttachment,XmATTACH_POSITION,
  557.                     XmNleftPosition,1,
  558.                     XmNrightAttachment,XmATTACH_POSITION,
  559.                     XmNrightPosition,2,
  560.                     NULL);
  561.         XmStringFree(xstr);
  562.         XtAddCallback(W_sd_ok,XmNactivateCallback,sd_okCB,NULL);
  563.  
  564.         xstr=XmStringCreate("Cancel",FONT_NORMAL);
  565.         W_sd_cancel
  566.           = XtVaCreateManagedWidget("sd_cancel",
  567.                     xmPushButtonWidgetClass,
  568.                     W_sd_action_form,
  569.                     XmNfontList,fontlist,
  570.                     XmNlabelString,xstr,
  571.                     XmNleftAttachment,XmATTACH_POSITION,
  572.                     XmNleftPosition,3,
  573.                     XmNrightAttachment,XmATTACH_POSITION,
  574.                     XmNrightPosition,4,
  575.                     NULL);
  576.         XmStringFree(xstr);
  577.         XtAddCallback(W_sd_cancel,XmNactivateCallback,sd_cancelCB,NULL);
  578.     }
  579.     
  580.     XtRealizeWidget(W_sd_dialog);
  581.     }
  582.     
  583.     XtPopup(W_sd_dialog,XtGrabNone);
  584. }   
  585.  
  586.  
  587. /*************************************************************************/
  588. void sd_okCB(Widget w, XtPointer client_data, XtPointer call_data)
  589. {
  590.     char *txt;
  591.     XmString xstr;
  592.     double new_alpha0;
  593.     double new_alphaDot0;
  594.     double new_a0;
  595.  
  596.     txt = XmTextGetString(W_sd_alpha0_text);
  597.     new_alpha0 = atof(txt)/180.0*PI;
  598.     XtFree(txt);
  599.     
  600.     txt = XmTextGetString(W_sd_alphaDot0_text);
  601.     new_alphaDot0 = atof(txt);
  602.     XtFree(txt);
  603.     
  604.     txt = XmTextGetString(W_sd_a0_text);
  605.     new_a0 = atof(txt);
  606.     XtFree(txt);
  607.  
  608.     if(new_alpha0<0.0 || new_alpha0>PI){
  609.     /* FEHLER: alpha0 */
  610.     char str[256];
  611.     
  612.     XBell(XtDisplay(W_toplevel),100);
  613.     
  614.     sprintf(str,"%6.2f",alpha0/PI*180.0);
  615.     XmTextSetString(W_sd_alpha0_text,str);
  616.     
  617.     xstr=XmStringCreateLtoR("FEHLER:\n0 <= alpha0 <= PI",FONT_NORMAL);
  618.     W_sd_alpha0_Error
  619.       = XmCreateMessageDialog(W_sd_alpha0_text,
  620.                   "sd_alpha0_Error",
  621.                   NULL,0);
  622.     XtVaSetValues(W_sd_alpha0_Error,
  623.               XmNdialogType,XmDIALOG_INFORMATION,
  624.               XmNmessageString,xstr,
  625.               NULL);
  626.     XmStringFree(xstr);
  627.     XtUnmanageChild(XmMessageBoxGetChild(W_sd_alpha0_Error,
  628.                          XmDIALOG_CANCEL_BUTTON));
  629.     XtUnmanageChild(XmMessageBoxGetChild(W_sd_alpha0_Error,
  630.                          XmDIALOG_HELP_BUTTON));
  631.     XtManageChild(W_sd_alpha0_Error);
  632.     XtPopup(XtParent(W_sd_alpha0_Error),XtGrabExclusive);
  633.     }else if(new_a0<=0.0 || new_a0>25.0){
  634.     /* FEHLER: a0 */
  635.     char str[256];
  636.     
  637.     XBell(XtDisplay(W_toplevel),100);
  638.     
  639.     sprintf(str,"%6.2f",a0);
  640.     XmTextSetString(W_sd_a0_text,str);
  641.     
  642.     xstr=XmStringCreateLtoR("FEHLER:\n0 < a0 <= 25",FONT_NORMAL);
  643.     W_sd_a0_Error
  644.       = XmCreateMessageDialog(W_sd_a0_text,
  645.                   "sd_a0_Error",
  646.                   NULL,0);
  647.     XtVaSetValues(W_sd_a0_Error,
  648.               XmNdialogType,XmDIALOG_ERROR,
  649.               XmNmessageString,xstr,
  650.               NULL);
  651.     XmStringFree(xstr);
  652.     XtUnmanageChild(XmMessageBoxGetChild(W_sd_a0_Error,
  653.                          XmDIALOG_CANCEL_BUTTON));
  654.     XtUnmanageChild(XmMessageBoxGetChild(W_sd_a0_Error,
  655.                          XmDIALOG_HELP_BUTTON));
  656.     XtManageChild(W_sd_a0_Error);
  657.     XtPopup(XtParent(W_sd_a0_Error),XtGrabExclusive);
  658.     }else{
  659.     alpha0    = new_alpha0;
  660.     alphaDot0 = new_alphaDot0;
  661.     a0        = new_a0;
  662.     
  663.     XtPopdown(W_sd_dialog);
  664.  
  665.     resetCB(0,0,0);
  666.     update_widgets(1);
  667.     }
  668. }
  669.  
  670. /*************************************************************************/
  671. void sd_cancelCB(Widget w, XtPointer client_data, XtPointer call_data)
  672. {
  673.     if(W_sd_alpha0_Error){
  674.     XtUnmanageChild(W_sd_alpha0_Error);
  675.     W_sd_alpha0_Error=NULL;
  676.     }
  677.     if(W_sd_a0_Error){
  678.     XtUnmanageChild(W_sd_a0_Error);
  679.     W_sd_a0_Error=NULL;
  680.     }
  681.     XtPopdown(W_sd_dialog);
  682. }
  683.  
  684. /*************************************************************************/
  685. void update_widgets(int all)
  686. {
  687.     int j;
  688.     XmString xstr;
  689.     char str[256];
  690.  
  691.     /*
  692.      * pendel-Widget
  693.      */
  694.     {
  695.     Dimension width;
  696.     
  697.     XtVaGetValues(W_core_pendel,
  698.               XmNwidth,&width,
  699.               NULL);
  700.  
  701.     XSetForeground(XtDisplay(W_core_pendel),gc_core_pendel,white);
  702.     XDrawLine(XtDisplay(W_core_pendel),
  703.           XtWindow(W_core_pendel),
  704.           gc_core_pendel,
  705.           (int)oldxpos,
  706.           Y_SIZE,
  707.           (int)oldxpos+(int)(Xscale*cos(range[ALPHA_RANGE].oldexact)),
  708.           Y_SIZE-(int)(Yscale*sin(range[ALPHA_RANGE].oldexact)));
  709.  
  710.     XSetForeground(XtDisplay(W_core_pendel),gc_core_pendel,black);
  711.     XDrawLine(XtDisplay(W_core_pendel),
  712.           XtWindow(W_core_pendel),
  713.           gc_core_pendel,
  714.           (int)xpos,
  715.           Y_SIZE,
  716.           (int)xpos+(int)(Xscale*cos(range[ALPHA_RANGE].exact)),
  717.           Y_SIZE-(int)(Yscale*sin(range[ALPHA_RANGE].exact)));
  718.     }
  719.  
  720.     /*
  721.      * angle-Widget
  722.      */
  723.     {
  724.     Dimension width;
  725.  
  726.     XtVaGetValues(W_core_angle,
  727.               XmNwidth,&width,
  728.               NULL);
  729.  
  730.     if((int)angle_xpos>=width){
  731.         XClearWindow(XtDisplay(W_core_angle),XtWindow(W_core_angle));
  732.  
  733.         XDrawLine(XtDisplay(W_core_angle),
  734.               XtWindow(W_core_angle),
  735.               gc_core_angle,
  736.               (int)1,Y_SIZE/2,
  737.               (int)(width-1),Y_SIZE/2);
  738.  
  739.         angle_xpos      = ANGLE_DELTA_X;
  740.         angle_oldxpos   = 0.0;
  741.         angle_ypos      = Y_SIZE/2 + 0.97*Y_SIZE/2*cos(range[ALPHA_RANGE].exact);
  742.         angle_oldypos   = Y_SIZE/2 + 0.97*Y_SIZE/2*cos(range[ALPHA_RANGE].exact);
  743.     }
  744.     
  745.     if(angle_tick++==(int)(1/ANGLE_DELTA_X)){
  746.         XSetForeground(XtDisplay(W_core_angle),gc_core_angle,black);
  747.  
  748.         XDrawLine(XtDisplay(W_core_angle),
  749.               XtWindow(W_core_angle),
  750.               gc_core_angle,
  751.               (int)1,Y_SIZE/2,
  752.               (int)(width-1),Y_SIZE/2);
  753.  
  754.         XDrawLine(XtDisplay(W_core_angle),
  755.               XtWindow(W_core_angle),
  756.               gc_core_angle,
  757.               (Position)angle_oldxpos,
  758.               (Position)angle_oldypos,
  759.               (Position)angle_xpos,
  760.               (Position)angle_ypos);
  761.  
  762.         angle_oldxpos = angle_xpos;
  763.         angle_oldypos = angle_ypos;
  764.         angle_xpos += ANGLE_DELTA_X;
  765.         angle_ypos = Y_SIZE/2 + 0.97*Y_SIZE/2*cos(range[ALPHA_RANGE].exact);
  766.         
  767.         angle_tick=0;
  768.     }
  769.     }
  770.     
  771.     /*
  772.      * 3 Ranges (alpha, alphaDot, a): Zahlenwerte
  773.      */
  774.     if(all){
  775.     /* Viele Werte */
  776.     for(j=0;j<3;j++){
  777.         int i;
  778.         
  779.         for(i=0;i<7;i++){
  780.         sprintf(str,"%5.3f",range[j].value[i].value);
  781.         xstr=XmStringCreate(str,FONT_NORMAL);
  782.         XtVaSetValues(range[j].value[i].W_value,
  783.                   XmNlabelString,xstr,
  784.                   NULL);
  785.         XmStringFree(xstr);
  786.         }
  787.     }
  788.     }
  789.     {
  790.     /* Gesamtwerte */
  791.     static int exactcnt=0;
  792.  
  793.     if(all || exactcnt++>25){
  794.         for(j=0;j<3;j++){
  795.         if(j==0){
  796.             sprintf(str,"%s = %4.1f°",range[j].title,range[j].exact/PI*180.0);
  797.         }else{
  798.             sprintf(str,"%s =%6.3f",range[j].title,range[j].exact);
  799.         }
  800.         xstr=XmStringCreate(str,FONT_NORMAL);
  801.         XtVaSetValues(range[j].W_exact,
  802.                   XmNlabelString,xstr,
  803.                   NULL);
  804.         XmStringFree(xstr);
  805.         }
  806.  
  807.         exactcnt=0;
  808.     }
  809.     }
  810.     
  811.     
  812.     /*
  813.      * 3 Ranges (alpha, alphaDot, a): Dreiecke
  814.      */
  815.     {
  816.     static int tricnt=0;
  817.     
  818.     if(all || tricnt++>25){
  819.         for(j=0;j<3;j++){
  820.         int i;
  821.         Dimension width;
  822.         double uppest,lowest,len;
  823.         Bound (*bound)[NRANGES];
  824.         Bound (*mbounds);
  825.         
  826.         XClearWindow(XtDisplay(range[j].W_core_values),
  827.                  XtWindow(range[j].W_core_values));
  828.         
  829.         switch(j){
  830.           case 0:
  831.             bound   = &alpha_bound;
  832.             mbounds = &alpha_mbounds;
  833.             break;
  834.           case 1:
  835.             bound   = &alphaDot_bound;
  836.             mbounds = &alphaDot_mbounds;
  837.             break;
  838.           case 2:
  839.             bound   = &a_bound;
  840.             mbounds = &a_mbounds;
  841.             break;
  842.           default:
  843.             abort();
  844.         };
  845.         
  846.         XtVaGetValues(range[j].W_core_values,
  847.                   XmNwidth,&width,
  848.                   NULL);
  849.         
  850.         lowest = (*mbounds).lower;
  851.         uppest = (*mbounds).upper;
  852.         len = uppest-lowest;
  853.         
  854.         for(i=0;i<NRANGES;i++){
  855.             int left,mid,right;
  856.             XPoint points[4];
  857.             
  858.             left  = (int)((((*bound)[i].lower) - lowest)/len*width);
  859.             right = (int)((((*bound)[i].upper) - lowest)/len*width);
  860.             mid   = (left+right)/2;
  861.             
  862.             XSetForeground(XtDisplay(range[j].W_core_values),
  863.                    range[j].gc_core_values,
  864.                    col_yellow.pixel);
  865.             points[0].x=(short)left +1;
  866.             points[0].y=(short)Y_SIZE;
  867.             points[1].x=(short)right -1;
  868.             points[1].y=(short)Y_SIZE;
  869.             points[2].x=(short)right-(mid-left)*range[j].value[i].value -1;
  870.             points[2].y=(short)Y_SIZE*(1-range[j].value[i].value);
  871.             points[3].x=(short)left+(mid-left)*range[j].value[i].value +1;
  872.             points[3].y=(short)Y_SIZE*(1-range[j].value[i].value);
  873.             XFillPolygon(XtDisplay(range[j].W_core_values),
  874.                  XtWindow(range[j].W_core_values),
  875.                  range[j].gc_core_values,
  876.                  points,4,
  877.                  Convex,CoordModeOrigin);
  878.         }
  879.         
  880.         for(i=0;i<NRANGES;i++){
  881.             int left,mid,right;
  882.             
  883.             left  = (int)((((*bound)[i].lower) - lowest)/len*width);
  884.             right = (int)((((*bound)[i].upper) - lowest)/len*width);
  885.             mid   = (left+right)/2;
  886.             
  887.             XSetForeground(XtDisplay(range[j].W_core_values),
  888.                    range[j].gc_core_values,black);
  889.             XDrawLine(XtDisplay(range[j].W_core_values),
  890.                   XtWindow(range[j].W_core_values),
  891.                   range[j].gc_core_values,
  892.                   left,Y_SIZE,
  893.                   mid,0);
  894.             XDrawLine(XtDisplay(range[j].W_core_values),
  895.                   XtWindow(range[j].W_core_values),
  896.                   range[j].gc_core_values,
  897.                   mid,0,
  898.                   right,Y_SIZE);
  899.         }
  900.         
  901.         XSetForeground(XtDisplay(range[j].W_core_values),
  902.                    range[j].gc_core_values,
  903.                    col_red.pixel);
  904.         XDrawLine(XtDisplay(range[j].W_core_values),
  905.               XtWindow(range[j].W_core_values),
  906.               range[j].gc_core_values,
  907.               (int)(((j==2?-1:1)*range[j].exact - lowest)/len*width),
  908.               0,
  909.               (int)(((j==2?-1:1)*range[j].exact - lowest)/len*width),
  910.               Y_SIZE);
  911.         }
  912.  
  913.         tricnt=0;
  914.     }
  915.     }
  916. }
  917.  
  918. /*************************************************************************/
  919. void update_values(void)
  920. {
  921.     double *alpha    = &range[ALPHA_RANGE].exact;
  922.     double *oldalpha = &range[ALPHA_RANGE].oldexact;
  923.     double *alphaDot = &range[ALPHA_DOT_RANGE].exact;
  924.     double Fres,rho,Fz,deltaAlpha;
  925.     double a;
  926.  
  927.     *oldalpha = *alpha;
  928.     oldxpos = xpos;
  929.  
  930.     a=balance(*alpha,*alphaDot);
  931.     Fa = m*a*a0;
  932.  
  933.     /* Pendel-Verhalten nach Ch. Ziegaus */
  934.     Fres        = sqrt(SQR(Fg) + SQR(Fa));
  935.     rho         = *alpha - acos(Fa/Fres);
  936.     Fz          = sin(rho) * Fres;
  937.     deltaAlpha  = Fz/(2.0*m*l)*SQR(deltaT) + *alphaDot*deltaT;
  938.     *alphaDot   = Fz/(m*l)*deltaT + *alphaDot;
  939.     *alpha      = *alpha + deltaAlpha;
  940.     xpos        = xpos + 0.5*a*SQR(deltaT)*A1;
  941.     
  942.     if(*alpha>PI){
  943.     *alpha = PI;
  944.     *alphaDot = 0.0;
  945.  
  946.     startstopCB(NULL,NULL,NULL);
  947.     }
  948.     if(*alpha<0){
  949.     *alpha = 0;
  950.     *alphaDot = 0.0;
  951.     
  952.     startstopCB(NULL,NULL,NULL);
  953.     }
  954. }
  955.  
  956. /*************************************************************************/
  957. void resetCB(Widget w, XtPointer client_data, XtPointer call_data)
  958. {
  959.     Dimension width;
  960.     
  961.     XtVaGetValues(W_core_pendel,
  962.           XmNwidth,&width,
  963.           NULL);
  964.     xpos = width/2;
  965.  
  966.     angle_tick=0;
  967.     angle_xpos     = ANGLE_DELTA_X;
  968.     angle_oldxpos  = 0.0;
  969.     angle_ypos     = Y_SIZE/2 + 0.97*Y_SIZE/2*cos(range[ALPHA_RANGE].exact);
  970.     angle_oldypos  = Y_SIZE/2 + 0.97*Y_SIZE/2*cos(range[ALPHA_RANGE].exact);
  971.  
  972.     range[ALPHA_RANGE].exact     = alpha0;
  973.     range[ALPHA_DOT_RANGE].exact = alphaDot0;
  974.     range[A_RANGE].exact         = 0.0;
  975.     Fa = m*balance(range[ALPHA_RANGE].exact,range[ALPHA_DOT_RANGE].exact);
  976.     Fg = m*g;
  977.  
  978.     if(!XtIsSensitive(W_step)){
  979.     startstopCB(NULL,NULL,NULL);
  980.     }
  981.  
  982.     XClearWindow(XtDisplay(W_core_pendel),XtWindow(W_core_pendel));
  983.     
  984.     XClearWindow(XtDisplay(W_core_angle),XtWindow(W_core_angle));
  985.     XSetForeground(XtDisplay(W_core_angle),gc_core_angle,black);
  986.     XDrawLine(XtDisplay(W_core_angle),
  987.           XtWindow(W_core_angle),
  988.           gc_core_angle,
  989.           (int)1,Y_SIZE/2,
  990.           (int)(width-1),Y_SIZE/2);
  991.  
  992.     update_widgets(1);
  993. }
  994.  
  995. /*************************************************************************/
  996. void aboutCB(Widget widget, XtPointer client_data, XtPointer call_data)
  997. {
  998.     Position x,y;
  999.     Dimension w,h;
  1000.     XmString xstr;
  1001.  
  1002.     if(!W_ab_dialog){
  1003.     XtVaGetValues(W_main,
  1004.               XmNwidth,&w,
  1005.               XmNheight,&h,
  1006.               XmNx,&x,
  1007.               XmNy,&y,
  1008.               NULL);
  1009.     
  1010.     xstr=XmStringCreateLtoR("Bitte warten!",FONT_NORMAL);
  1011.     W_ab_dialog
  1012.       = XmCreateMessageDialog(W_toplevel,
  1013.                   "ab_dialog",
  1014.                   NULL,0);
  1015.     XtVaSetValues(W_ab_dialog,
  1016.               XmNdialogType,XmDIALOG_ERROR,
  1017.               XmNmessageString,xstr,
  1018.               NULL);
  1019.     XmStringFree(xstr);
  1020.     XtUnmanageChild(XmMessageBoxGetChild(W_ab_dialog,
  1021.                          XmDIALOG_CANCEL_BUTTON));
  1022.     XtUnmanageChild(XmMessageBoxGetChild(W_ab_dialog,
  1023.                          XmDIALOG_HELP_BUTTON));
  1024.     XtRealizeWidget(W_ab_dialog);
  1025.     XtManageChild(W_ab_dialog);
  1026.     }
  1027.     XtPopup(XtParent(W_ab_dialog),XtGrabExclusive);
  1028.  
  1029.     signal(SIGALRM,aboutAlarm);
  1030.     alarm(5);
  1031.  
  1032.     system("mosaic http://rfhs1012.fh.uni-regensburg.de/usergroups/wwwki/FuzzyPendel/ &");
  1033. }
  1034.  
  1035. /*************************************************************************/
  1036. void aboutAlarm(int sig)
  1037. {
  1038.     XtPopdown(XtParent(W_ab_dialog));
  1039. }
  1040.       
  1041. /*************************************************************************/
  1042. void quitCB(Widget w, XtPointer client_data, XtPointer call_data)
  1043. {
  1044.     exit(0);
  1045. }
  1046.  
  1047. /*************************************************************************/
  1048. void startstopCB(Widget w, XtPointer client_data, XtPointer call_data)
  1049. {
  1050.     XmString xstr;
  1051.     
  1052.     if(XtIsSensitive(W_step)){
  1053.     /* start */
  1054.     XtSetSensitive(W_step,False);
  1055.  
  1056.     xstr=XmStringCreate("Stop",FONT_NORMAL);
  1057.     XtVaSetValues(W_startstop,
  1058.               XmNlabelString,xstr,
  1059.               NULL);
  1060.     XmStringFree(xstr);
  1061.  
  1062.     XtAppAddTimeOut(app_context,PERIOD_SOME,(XtTimerCallbackProc)periodicTO,
  1063.             (XtPointer)0);
  1064.     }else{
  1065.     /* stop */
  1066.     XtSetSensitive(W_step,True);
  1067.     
  1068.     xstr=XmStringCreate("Start",FONT_NORMAL);
  1069.     XtVaSetValues(W_startstop,
  1070.               XmNlabelString,xstr,
  1071.               NULL);
  1072.     XmStringFree(xstr);
  1073.  
  1074.     update_widgets(1);
  1075.     }
  1076. }
  1077.  
  1078. /*************************************************************************/
  1079. void pushCB(Widget w, XtPointer client_data, XtPointer call_data)
  1080. {
  1081.     double *alpha    = &range[ALPHA_RANGE].exact;
  1082.     double *oldalpha = &range[ALPHA_RANGE].oldexact;
  1083.     double *alphaDot = &range[ALPHA_DOT_RANGE].exact;
  1084.  
  1085.     *oldalpha = *alpha;
  1086.     oldxpos = xpos;
  1087.  
  1088.     angle_oldypos=angle_ypos;
  1089.     
  1090.     if(client_data){
  1091.     /* Push to right */
  1092.     *alpha    -= Bumper_alpha;
  1093.     *alphaDot -= Bumper_alphaDot;
  1094.     
  1095.     if(*alpha < 0.0){
  1096.         *alpha    = 0.0;
  1097.         *alphaDot = 0.0;
  1098.  
  1099.         startstopCB(NULL,NULL,NULL);
  1100.     }
  1101.     }else{
  1102.     /* Push to left */
  1103.     *alpha    += Bumper_alpha;
  1104.     *alphaDot += Bumper_alphaDot;
  1105.  
  1106.     if(*alpha>PI){
  1107.         *alpha    = PI;
  1108.         *alphaDot = 0.0;
  1109.         
  1110.         startstopCB(NULL,NULL,NULL);
  1111.     }
  1112.     }
  1113.  
  1114.     if(XtIsSensitive(W_step)){
  1115.     update_widgets(1);
  1116.     }else{
  1117.     update_widgets(0);
  1118.     }
  1119. }
  1120.  
  1121. /*************************************************************************/
  1122. void init(int argc, char *argv[])
  1123. {
  1124.     int i;
  1125.  
  1126.     /* Bereichs-Ueberschriften */
  1127.     range[0].title="alpha";
  1128.     range[1].title="alphaDot";
  1129.     range[2].title="a";
  1130.  
  1131.     for(i=0;i<NRANGES;i++){
  1132.     alpha_bound[i].lower = alpha_bound[i].lower*PI/180.0;
  1133.     alpha_bound[i].upper = alpha_bound[i].upper*PI/180.0;
  1134.     }
  1135.     alpha_mbounds.upper =    alpha_mbounds.upper*PI/180.0;
  1136.     alpha_mbounds.lower =    alpha_mbounds.lower*PI/180.0;
  1137.  
  1138.     /* alpha0 und alphaDot0 ueber Befehlszeile oder Defaults */
  1139.     if(argc>3){
  1140.     alpha0    = atof(argv[1])/180.0*PI;
  1141.     alphaDot0 = atof(argv[2]);
  1142.     a0        = atof(argv[3]);
  1143.  
  1144.     if(a0>25.0 || a0<=0.0){
  1145.         fprintf(stderr,"a0 must be in ]0.0;25.0]\n");
  1146.         exit(1);
  1147.     }      
  1148.     }else{
  1149.     if(argc==1){
  1150.         alpha0    = ALPHA0;
  1151.         alphaDot0 = ALPHA_DOT0;
  1152.         a0        = A0;
  1153.     }else{
  1154.         fprintf(stderr,"Usage: %s alpha alphaDot a0\n",argv[0]);
  1155.         fprintf(stderr,"Defaults are alpha    = %7.4f°\n",ALPHA0/PI*180.0);
  1156.         fprintf(stderr,"             alphaDot = %7.4f\n",ALPHA_DOT0);
  1157.         fprintf(stderr,"             a0       = %7.4f\n",A0);
  1158.         exit(1);
  1159.     }
  1160.     }
  1161.  
  1162.     /* Anfangslage des Pendels, sollte ueber Dialog geregelt werden!!! */
  1163.     range[ALPHA_RANGE].exact     = alpha0;
  1164.     range[ALPHA_RANGE].oldexact  = alpha0;
  1165.     range[ALPHA_DOT_RANGE].exact = alphaDot0;
  1166.     range[A_RANGE].exact         = 0.0;
  1167.     Fa = m*balance(range[ALPHA_RANGE].exact,range[ALPHA_DOT_RANGE].exact);
  1168.     Fg = m*g;
  1169.     xpos = X_SIZE/2;
  1170.  
  1171.     /* angle-Widget */
  1172.     angle_tick=0;
  1173.     angle_xpos    = ANGLE_DELTA_X;
  1174.     angle_oldxpos = 0.0;
  1175.     angle_ypos    = Y_SIZE/2 + 0.97*Y_SIZE/2*cos(range[ALPHA_RANGE].exact);
  1176.     angle_oldypos = Y_SIZE/2 + 0.97*Y_SIZE/2*cos(range[ALPHA_RANGE].exact);
  1177. }
  1178.  
  1179. /*************************************************************************/
  1180. int main(int argc, char *argv[])
  1181. {
  1182.     char str[256];
  1183.     char str1[256];
  1184.     XmString xstr;
  1185.  
  1186.     init(argc, argv);
  1187.  
  1188.     W_toplevel = XtVaAppInitialize(&app_context,
  1189.                    "XPendel7",
  1190.                    NULL,0,
  1191.                    &argc, argv,
  1192.                    NULL,
  1193.                    NULL);
  1194.  
  1195.     /* Fonts initialisieren */
  1196.     fontlist=XmFontListCreate(XLoadQueryFont(XtDisplay(W_toplevel),FONT_NORMAL_NAME),
  1197.                   FONT_NORMAL);
  1198.     fontlist=XmFontListAdd(fontlist,
  1199.                XLoadQueryFont(XtDisplay(W_toplevel),FONT_BIG_NAME),
  1200.                FONT_BIG);
  1201.  
  1202.     W_main = XtVaCreateManagedWidget("main",
  1203.                      xmMainWindowWidgetClass,
  1204.                      W_toplevel,
  1205.                      XmNwidth,X_SIZE,
  1206.                      NULL);
  1207.       
  1208.     {
  1209.     /* Menubar */
  1210.     W_menubar
  1211.       = XmCreateMenuBar(W_main,"menubar",NULL,0);
  1212.     W_file_menu
  1213.       = XmCreatePulldownMenu(W_menubar,"W_file_menu",NULL,0);
  1214.  
  1215.     xstr=XmStringCreate("File",FONT_NORMAL);
  1216.     W_file_foobar
  1217.       = XtVaCreateManagedWidget("file_foobar",
  1218.                     xmCascadeButtonWidgetClass,
  1219.                     W_menubar,
  1220.                     XmNlabelString,xstr,
  1221.                     XmNfontList,fontlist,
  1222.                     XmNmnemonic,'F',
  1223.                     XmNsubMenuId,W_file_menu,
  1224.                     NULL);
  1225.     XmStringFree(xstr);
  1226.  
  1227.     xstr=XmStringCreate("Reset",FONT_NORMAL);
  1228.     W_reset_menuitem
  1229.       = XtVaCreateManagedWidget("reset_menuitem",
  1230.                     xmPushButtonGadgetClass,
  1231.                     W_file_menu,
  1232.                     XmNlabelString,xstr,
  1233.                     XmNmnemonic,'R',
  1234.                     NULL);
  1235.     XmStringFree(xstr);
  1236.     XtAddCallback(W_reset_menuitem,XmNactivateCallback,
  1237.               resetCB,NULL);
  1238.  
  1239.     xstr=XmStringCreate("Set Defaults",FONT_NORMAL);
  1240.     W_setdefaults_menuitem
  1241.       = XtVaCreateManagedWidget("setdefaults_menuitem",
  1242.                     xmPushButtonGadgetClass,
  1243.                     W_file_menu,
  1244.                     XmNlabelString,xstr,
  1245.                     XmNmnemonic,'V',
  1246.                     NULL);
  1247.     XmStringFree(xstr);
  1248.     XtAddCallback(W_setdefaults_menuitem,XmNactivateCallback,
  1249.               setdefaultsCB,NULL);
  1250.  
  1251.     xstr=XmStringCreate("About",FONT_NORMAL);
  1252.     W_about_menuitem
  1253.       = XtVaCreateManagedWidget("about_menuitem",
  1254.                     xmPushButtonGadgetClass,
  1255.                     W_file_menu,
  1256.                     XmNlabelString,xstr,
  1257.                     XmNmnemonic,'A',
  1258.                     NULL);
  1259.     XmStringFree(xstr);
  1260.     XtAddCallback(W_about_menuitem,XmNactivateCallback,
  1261.               aboutCB,NULL);
  1262.  
  1263.     W_sep_menuitem
  1264.       = XtVaCreateManagedWidget("sep_menuitem",
  1265.                     xmSeparatorGadgetClass,
  1266.                     W_file_menu,
  1267.                     NULL);
  1268.  
  1269.     xstr=XmStringCreate("Quit",FONT_NORMAL);
  1270.     W_quit_menuitem
  1271.       = XtVaCreateManagedWidget("quit_menuitem",
  1272.                     xmPushButtonGadgetClass,
  1273.                     W_file_menu,
  1274.                     XmNlabelString,xstr,
  1275.                     XmNmnemonic,'Q',
  1276.                     NULL);
  1277.     XmStringFree(xstr);
  1278.     XtAddCallback(W_quit_menuitem,XmNactivateCallback,
  1279.               quitCB,NULL);
  1280.  
  1281.     XtManageChild(W_menubar);
  1282.     }
  1283.  
  1284.     W_rc_outer = XtVaCreateManagedWidget("rc_outer",
  1285.                      xmRowColumnWidgetClass,
  1286.                      W_main,
  1287.                      XmNorientation,XmVERTICAL,
  1288.                      NULL);
  1289.     {
  1290.     /* Titel */
  1291.     W_title_form
  1292.       = XtVaCreateManagedWidget("title_form",
  1293.                     xmFormWidgetClass,
  1294.                     W_rc_outer,
  1295.                     XmNfractionBase,1,
  1296.                     NULL);
  1297.     
  1298.     xstr=XmStringCreate("Fuzzy-Pendel",FONT_BIG);
  1299.     W_title
  1300.       = XtVaCreateManagedWidget("title",
  1301.                     xmLabelWidgetClass,
  1302.                     W_title_form,
  1303.                     XmNlabelString,xstr,
  1304.                     XmNfontList,fontlist,
  1305.                     XmNalignment,XmALIGNMENT_CENTER,
  1306.                     XmNleftAttachment,XmATTACH_POSITION,
  1307.                     XmNleftPosition,0,
  1308.                     XmNrightAttachment,XmATTACH_POSITION,
  1309.                     XmNrightPosition,1,
  1310.                     NULL);
  1311.     XmStringFree(xstr);
  1312.     }
  1313.     
  1314.     W_sep1
  1315.       = XtVaCreateManagedWidget("sep1",
  1316.                 xmSeparatorWidgetClass,
  1317.                 W_rc_outer,
  1318.                 NULL);
  1319.     {
  1320.     {
  1321.         /* Pendel-Widget mit zwei Pfeilen */
  1322.         W_form_pendel
  1323.           = XtVaCreateManagedWidget("form_pendel",
  1324.                     xmFormWidgetClass,
  1325.                     W_rc_outer,
  1326.                     XmNfractionBase,PENDEL_FRACTION,
  1327.                     NULL);
  1328.         {
  1329.         {
  1330.             /* Left Arrow */
  1331.             W_push_left
  1332.               = XtVaCreateManagedWidget("push_left",
  1333.                         xmArrowButtonWidgetClass,
  1334.                         W_form_pendel,
  1335.                         XmNwidth,Y_SIZE/3,
  1336.                         XmNarrowDirection,XmARROW_LEFT,
  1337.                         XmNtopAttachment,XmATTACH_FORM,
  1338.                         XmNbottomAttachment,XmATTACH_FORM,
  1339.                         XmNleftAttachment,XmATTACH_POSITION,
  1340.                         XmNleftPosition,0,
  1341.                         XmNrightAttachment,XmATTACH_POSITION,
  1342.                         XmNrightPosition,1,
  1343.                         NULL);
  1344.             XtAddCallback(W_push_left,XmNactivateCallback,pushCB,0);
  1345.         }
  1346.         {
  1347.             /* Pendel-core */
  1348.             W_core_pendel
  1349.               = XtVaCreateManagedWidget("pendel_angle",
  1350.                         coreWidgetClass,
  1351.                         W_form_pendel,
  1352.                         XmNheight, Y_SIZE,
  1353.                         XmNwidth,  X_SIZE-(2*Y_SIZE/3),
  1354.                         XmNleftAttachment,XmATTACH_POSITION,
  1355.                         XmNleftPosition,1,
  1356.                         XmNrightAttachment,XmATTACH_POSITION,
  1357.                         XmNrightPosition,PENDEL_FRACTION-1,
  1358.                         NULL);
  1359.         }
  1360.         {
  1361.             /* Right Arrow */
  1362.             W_push_right
  1363.               = XtVaCreateManagedWidget("push_right",
  1364.                         xmArrowButtonWidgetClass,
  1365.                         W_form_pendel,
  1366.                         XmNwidth,Y_SIZE/3,
  1367.                         XmNtopAttachment,XmATTACH_FORM,
  1368.                         XmNbottomAttachment,XmATTACH_FORM,
  1369.                         XmNarrowDirection,XmARROW_RIGHT, 
  1370.                         XmNleftAttachment,XmATTACH_POSITION,
  1371.                         XmNleftPosition,PENDEL_FRACTION-1,
  1372.                         XmNrightAttachment,XmATTACH_POSITION,
  1373.                         XmNrightPosition,PENDEL_FRACTION,
  1374.                         NULL);
  1375.             XtAddCallback(W_push_right,
  1376.                   XmNactivateCallback,
  1377.                   pushCB,
  1378.                   (XtPointer)1);
  1379.         }
  1380.         }
  1381.     }
  1382.     {
  1383.         /* Angle-core-Widget */
  1384.  
  1385.         W_core_angle
  1386.          = XtVaCreateManagedWidget("W_core_angle",
  1387.                        coreWidgetClass,
  1388.                        W_rc_outer,
  1389.                        XmNheight, Y_SIZE,
  1390.                        XmNwidth,  X_SIZE,
  1391.                        NULL);
  1392.     }
  1393.     {
  1394.         W_form_ranges = XtVaCreateManagedWidget("form_ranges",
  1395.                             xmFormWidgetClass,
  1396.                             W_rc_outer,
  1397.                             XmNfractionBase,3,
  1398.                             NULL);
  1399.         {
  1400.         int j;
  1401.  
  1402.         for(j=0;j<3;j++){
  1403.             int i;
  1404.             
  1405.             sprintf(str,"%s_frame",range[j].title);
  1406.             range[j].W_frame
  1407.               = XtVaCreateManagedWidget(str,
  1408.                         xmFrameWidgetClass,
  1409.                         W_form_ranges,
  1410.                         XmNleftAttachment,XmATTACH_POSITION,
  1411.                         XmNleftPosition,j,
  1412.                         XmNrightAttachment,XmATTACH_POSITION,
  1413.                         XmNrightPosition,j+1,
  1414.                         NULL);
  1415.             
  1416.             sprintf(str,"%s_box",range[j].title);
  1417.             range[j].W_box
  1418.               = XtVaCreateManagedWidget(str,
  1419.                         xmRowColumnWidgetClass,
  1420.                         range[j].W_frame,
  1421.                         XmNisAligned,False,
  1422.                         XmNorientation,XmVERTICAL,
  1423.                         NULL);
  1424.  
  1425.             sprintf(str,"%s_title",range[j].title);
  1426.             xstr=XmStringCreate(range[j].title,FONT_NORMAL);
  1427.             range[j].W_title
  1428.               = XtVaCreateManagedWidget(str,
  1429.                         xmLabelWidgetClass,
  1430.                         range[j].W_box,
  1431.                         XmNfontList,fontlist,
  1432.                         XmNlabelString,xstr,
  1433.                         XmNalignment,XmALIGNMENT_CENTER,
  1434.                         NULL);
  1435.             XmStringFree(xstr);
  1436.             
  1437.             sprintf(str,"%s_sep1",range[j].title);
  1438.             range[j].W_sep1
  1439.               = XtVaCreateManagedWidget(str,
  1440.                         xmSeparatorWidgetClass,
  1441.                         range[j].W_box,
  1442.                         NULL);
  1443.  
  1444.             for(i=0;i<7;i++){
  1445.             sprintf(str,"%s_%s_form",range[j].title,range_name[i]);
  1446.             range[j].value[i].W_form
  1447.               = XtVaCreateManagedWidget(str,
  1448.                             xmFormWidgetClass,
  1449.                             range[j].W_box,
  1450.                             NULL);
  1451.             
  1452.             sprintf(str,"%s_%s_label",range[j].title,range_name[i]);
  1453.             sprintf(str1,"%s: ",range_name[i]);
  1454.             xstr=XmStringCreate(str1,FONT_NORMAL);
  1455.             range[j].value[i].W_label
  1456.               = XtVaCreateManagedWidget(str,
  1457.                             xmLabelWidgetClass,
  1458.                             range[j].value[i].W_form,
  1459.                             XmNfontList,fontlist,
  1460.                             XmNlabelString,xstr,
  1461.                             XmNalignment,XmALIGNMENT_BEGINNING,
  1462.                             XmNleftAttachment,XmATTACH_FORM,
  1463.                             NULL);
  1464.             XmStringFree(xstr);
  1465.             
  1466.             sprintf(str,"%s_%s_value",range[j].title,range_name[i]);
  1467.             sprintf(str1,"%5.3f",range[j].value[i].value);
  1468.             xstr=XmStringCreate(str1,FONT_NORMAL);
  1469.             range[j].value[i].W_value
  1470.               = XtVaCreateManagedWidget(str,
  1471.                             xmLabelWidgetClass,
  1472.                             range[j].value[i].W_form,
  1473.                             XmNfontList,fontlist,
  1474.                             XmNlabelString,xstr,
  1475.                             XmNalignment,XmALIGNMENT_END,
  1476.                             XmNleftAttachment,XmATTACH_WIDGET,
  1477.                             XmNleftWidget,range[j].value[i].W_label,
  1478.                             XmNrightAttachment,XmATTACH_FORM,
  1479.                             NULL);
  1480.             }
  1481.             sprintf(str,"%s_sep2",range[j].title);
  1482.             range[j].W_sep1
  1483.               = XtVaCreateManagedWidget(str,
  1484.                         xmSeparatorWidgetClass,
  1485.                         range[j].W_box,
  1486.                         NULL);
  1487.             sprintf(str,"%s_core_values",range[j].title);
  1488.             range[j].W_core_values
  1489.               = XtVaCreateManagedWidget(str,
  1490.                         coreWidgetClass,
  1491.                         range[j].W_box,
  1492.                         XmNheight,Y_SIZE,
  1493.                         XmNleftAttachment,XmATTACH_FORM,
  1494.                         XmNrightAttachment,XmATTACH_FORM,
  1495.                         XmNbottomAttachment,XmATTACH_FORM,
  1496.                         XmNtopAttachment,XmATTACH_WIDGET,
  1497.                         XmNtopWidget,range[j].W_sep1,
  1498.                         NULL);
  1499.  
  1500.         }
  1501.         }
  1502.     }
  1503.     {
  1504.         int i;
  1505.         
  1506.         W_form_exacts = XtVaCreateManagedWidget("form_exacts",
  1507.                             xmFormWidgetClass,
  1508.                             W_rc_outer,
  1509.                             XmNfractionBase,3,
  1510.                             NULL);
  1511.  
  1512.         for(i=0;i<3;i++){
  1513.         sprintf(str,"%s_W_exact",range[i].title);
  1514.         if(i==0){
  1515.             sprintf(str1,"%s = %4.1f°",range[i].title,range[i].exact/PI*180.0);
  1516.         }else{
  1517.             sprintf(str1,"%s =%6.3f",range[i].title,range[i].exact);
  1518.         }
  1519.         xstr=XmStringCreate(str1,FONT_NORMAL);
  1520.         range[i].W_exact = XtVaCreateManagedWidget(str,
  1521.                                xmLabelWidgetClass,
  1522.                                W_form_exacts,
  1523.                                XmNfontList,fontlist,
  1524.                                XmNlabelString,xstr,
  1525.                                XmNleftAttachment,XmATTACH_POSITION,
  1526.                                XmNleftPosition,i,
  1527.                                XmNrightAttachment,XmATTACH_POSITION,
  1528.                                XmNrightPosition,i+1,
  1529.                                XmNalignment,XmALIGNMENT_BEGINNING,
  1530.                                NULL);
  1531.         XmStringFree(xstr);
  1532.         }
  1533.     }
  1534.     
  1535.     W_sep2 = XtVaCreateManagedWidget("sep2",
  1536.                      xmSeparatorWidgetClass,
  1537.                      W_rc_outer,
  1538.                      NULL);
  1539.     W_form_bottom = XtVaCreateManagedWidget("form_bottom",
  1540.                         xmFormWidgetClass,
  1541.                         W_rc_outer,
  1542.                         XmNfractionBase,10,
  1543.                         NULL);
  1544.     {
  1545.         xstr=XmStringCreate("Start",FONT_NORMAL);
  1546.         W_startstop = XtVaCreateManagedWidget("startstop",
  1547.                           xmPushButtonWidgetClass,
  1548.                           W_form_bottom,
  1549.                           XmNfontList,fontlist,
  1550.                           XmNlabelString,xstr,
  1551.                           XmNleftAttachment,XmATTACH_POSITION,
  1552.                           XmNleftPosition,1,
  1553.                           XmNrightAttachment,XmATTACH_POSITION,
  1554.                           XmNrightPosition,3,
  1555.                           NULL);
  1556.         XtAddCallback(W_startstop,
  1557.               XmNactivateCallback,
  1558.               startstopCB,
  1559.               (XtPointer)1);
  1560.         XmStringFree(xstr);
  1561.  
  1562.         xstr=XmStringCreate("Step",FONT_NORMAL);
  1563.         W_step = XtVaCreateManagedWidget("step",
  1564.                          xmPushButtonWidgetClass,
  1565.                          W_form_bottom,
  1566.                          XmNfontList,fontlist,
  1567.                          XmNlabelString,xstr,
  1568.                          XmNleftAttachment,XmATTACH_POSITION,
  1569.                          XmNleftPosition,4,
  1570.                          XmNrightAttachment,XmATTACH_POSITION,
  1571.                          XmNrightPosition,6,
  1572.                          NULL);
  1573.         XtAddCallback(W_step,
  1574.               XmNactivateCallback,
  1575.               stepCB,
  1576.               (XtPointer)1);
  1577.         XtSetSensitive(W_step,True);
  1578.         XmStringFree(xstr);
  1579.  
  1580.         xstr=XmStringCreate("Quit",FONT_NORMAL);
  1581.         W_quit = XtVaCreateManagedWidget("quit",
  1582.                          xmPushButtonWidgetClass,
  1583.                          W_form_bottom,
  1584.                          XmNfontList,fontlist,
  1585.                          XmNlabelString,xstr,
  1586.                          XmNleftAttachment,XmATTACH_POSITION,
  1587.                          XmNleftPosition,7,
  1588.                          XmNrightAttachment,XmATTACH_POSITION,
  1589.                          XmNrightPosition,9,
  1590.                          NULL);
  1591.         XtAddCallback(W_quit,
  1592.               XmNactivateCallback,
  1593.               quitCB,
  1594.               (XtPointer)1);
  1595.         XmStringFree(xstr);
  1596.     }
  1597.     }
  1598.  
  1599.     XtRealizeWidget(W_toplevel);
  1600.  
  1601.     {
  1602.     int screen;
  1603.     int i;
  1604.     Display *display;
  1605.     
  1606.     /* core_angle-init */
  1607.     display = XtDisplay(W_rc_outer);
  1608.     screen  = DefaultScreen(display);
  1609.  
  1610.     black = BlackPixel(display,screen);
  1611.     white = WhitePixel(display,screen);
  1612.  
  1613.     gc_core_angle  = XCreateGC(display,XtWindow(W_core_angle),0,NULL);
  1614.     XSetForeground(display,gc_core_angle,black);
  1615.     XSetBackground(display,gc_core_angle,white);
  1616.  
  1617.     gc_core_pendel  = XCreateGC(display,XtWindow(W_core_pendel),0,NULL);
  1618.     XSetForeground(display,gc_core_pendel,black);
  1619.     XSetBackground(display,gc_core_pendel,white);
  1620.  
  1621.     cmap=DefaultColormap(display,screen);
  1622.     col_red.red   = 255<<8;
  1623.     col_red.green =   0<<8;
  1624.     col_red.blue  =   0<<8;
  1625.     XAllocColor(display, cmap, &col_red);
  1626.     
  1627.     col_yellow.red   = 255<<8;
  1628.     col_yellow.green = 255<<8;
  1629.     col_yellow.blue  =   0<<8;
  1630.     XAllocColor(display, cmap, &col_yellow);
  1631.  
  1632.     for(i=0;i<3;i++){
  1633.         range[i].gc_core_values
  1634.           = XCreateGC(display,XtWindow(range[i].W_core_values),0,NULL);
  1635.         XSetForeground(display,range[i].gc_core_values,black);
  1636.         XSetBackground(display,range[i].gc_core_values,white);
  1637.     }
  1638.     }
  1639.     XFlush(XtDisplay(W_toplevel));
  1640.  
  1641.     {
  1642.     int i;
  1643.     for(i=0;i<10;i++)
  1644.       update_widgets(1);
  1645.     resetCB(0,0,0);
  1646.     }
  1647.  
  1648.     XtAppMainLoop(app_context);
  1649.     /*NOTREACHED*/
  1650.     return 0;
  1651. }
  1652.