home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 215 / DDJ11A92.ZIP / WIDGET.ASC < prev    next >
Text File  |  1992-10-29  |  12KB  |  310 lines

  1. _DEBUGGING MOTIF WIDGETS_
  2. by Kamran Husain
  3.  
  4. [LISTING ONE]
  5.  
  6. /* This code is given as an example of sorts for you to write your own Motif 
  7. ** application. Compile this program with the line:
  8. **  acc -g test.c -o testme LineChart.o BarChart.o -lXm -lXt -lX11 -lm
  9. **  where 
  10. **      acc - is the ANSI compiler at your site
  11. **      -g  - is the debug option (optional)
  12. **        -o  - specifies the output executable filename
  13. **      -lXm - is the Motif Library 
  14. **      -lXt - is the Intrinsics Library 
  15. **      -lX11 - is the X11 Library 
  16. **      -lm - math library.
  17. **      LineChart.o and BarChart.o are object files from the
  18. **      sources available electronically from Dr Dobbs.
  19. ** If you want to step thru this code in a debugger and examine the internals 
  20. ** of the Widgets themselves, replace the next #include "LineChart.h" line 
  21. ** outside the comments with
  22. **  #include "BarChartP.h" 
  23. **  #include "BarChart.h"
  24. **  #include "LineChartP.h"
  25. **  #include "LineChart.h"
  26. */
  27.  
  28. /* Some standard include files here. */
  29. #include <X11/X.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <math.h>
  33. #include <X11/StringDefs.h>
  34. #include <X11/Intrinsic.h>
  35. #include <X11/Shell.h>
  36. #include <Xm/Xm.h>
  37. #include <Xm/PushB.h>
  38. #include <Xm/Form.h>
  39. #include "LineChart.h"
  40.  
  41. /* A macro to facilitate button placement on a form. The x,y are the top left 
  42. ** corner on the form. The w is the right position relative to the form's left 
  43. ** side the h is the bottom position relative to the form's top side */
  44. #define MAKE_BTN_ON_FORM(form,btn,x,y,w,h,str) \
  45.     n = 0;  \
  46.     XtSetArg(wars[n], XmNleftAttachment, XmATTACH_POSITION ); n++; \
  47.     XtSetArg(wars[n], XmNtopAttachment, XmATTACH_POSITION ); n++; \
  48.     XtSetArg(wars[n], XmNbottomAttachment, XmATTACH_POSITION ); n++; \
  49.     XtSetArg(wars[n], XmNrightAttachment, XmATTACH_POSITION ); n++; \
  50.     XtSetArg(wars[n], XmNrightPosition, (x+w)); n++; \
  51.     XtSetArg(wars[n], XmNleftPosition, (x)); n++; \
  52.     XtSetArg(wars[n], XmNtopPosition, (y)); n++; \
  53.     XtSetArg(wars[n], XmNbottomPosition, (h+y)); n++; \
  54.     btn = XmCreatePushButton(form,str,wars,n); \
  55.     XtManageChild(btn)
  56. /*  Remove the comments below to enable some debug levels.  
  57.     #define DEBUG_SWAPPING_SCREENS
  58.     #define DEBUG_LIMITS 
  59.     #define DEBUG_SI_COUNTER
  60. */
  61. #define  ScrnWidth 500 
  62. #define  ScrnHt    400
  63. #define MAXITEMS 10
  64. Widget mainShell,       /* Application shell   */ 
  65.        mainForm,        /* Master form         */
  66.       plotLChart,       /* Line Chart Widget   */ 
  67.       plotBChart,       /* Bar Chart Widget    */
  68.       otherPBtn,        /* Toggle Push Button  */
  69.       advancePBtn,  /* Advance Data in Lists Push Button */
  70.       donePBtn;     /* Exit Push Button    */ 
  71. /* Pixels are stored in these. */
  72. unsigned long WhiteColor, 
  73.             BlackColor,
  74.             BlueColor, 
  75.             RedColor,
  76.             GreenColor;
  77.  
  78. /* Storage Area for the dummy data.
  79.    int dummyOne[MAXITEMS]  = { -10. -5, 0, 15, 20, 15 ,0, -5, -10, -5 }; 
  80.    int dummyTwo[MAXITEMS]  = { 4, 13, 13, 10 ,11, 9, 4, -11, -13, -11 }; 
  81. */
  82. static int siCounter = MAXITEMS - 1; 
  83. int one[MAXITEMS];
  84. int two[MAXITEMS]; 
  85. /*  Declare the functions and callbacks here. Note that I do not use any 
  86. **  parameters into the callbacks. Please refer to the Motif manual for 
  87. **  details on these parameters if you need to use them. */
  88. void exitCB(); 
  89. int  toggleCB(); 
  90. int  advanceCB(); 
  91. void createDummyData(int count, int *oneptr, int *twoptr); 
  92. unsigned long str2pix(char *spec, Widget w); 
  93. int main(int argc, char *argv[])
  94. {
  95.     Arg wars[24];       /* for argument passing     */
  96.     XGCValues  gcv; /* for creation for GC      */
  97.     XtGCMask  gcmask;   /* for GC flags             */
  98.     char strName[24];   /* Dummy storage area       */
  99.     int FormHt = 88;    /* On the main form         */
  100.     int margin = 10;    /* Distance between buttons */ 
  101.     int dw = 20;        /* Width of each button     */
  102.     int dh = 10;        /* Height of each button    */
  103.     int h1 = margin;    /* temporary var initialize */ 
  104.     int h2;             /* temporary variables      */ 
  105.     int DispHt, DispWd, ivalue, n, i, imax, imin, imid; 
  106.     /* Initialize toolkit */
  107.     mainShell = XtInitialize(argv[0],"Demo", NULL, NULL, &argc, argv) ;
  108.     n =0;
  109.     XtSetArg(wars[n], XmNwidth, ScrnWidth); n++;
  110.     XtSetArg(wars[n], XmNheight, ScrnHt); n++;
  111.     XtSetArg(wars[n], XmNiconic, False ); n++;
  112.     XtSetArg(wars[n], XmNiconName, "TestMe"); n++;
  113.     XtSetValues(mainShell,wars,n);  
  114.     XtRealizeWidget(mainShell);
  115.     /* Place the Form on the Shell. */
  116.     n=0;
  117.     XtSetArg(wars[n], XmNwidth, ScrnWidth); n++;
  118.     XtSetArg(wars[n], XmNheight, ScrnHt); n++;
  119.     mainForm = XmCreateForm(mainShell,"mainForm",wars,n);
  120.     XtManageChild( mainForm );
  121.     /* Use macros to place PushButtons on Form. Attach callbacks too. */
  122. MAKE_BTN_ON_FORM(mainForm,otherPBtn,h1,FormHt,dw,dh,"Toggle");
  123.      h2 = h1 + margin + dw; 
  124. MAKE_BTN_ON_FORM(mainForm,advancePBtn,h2,FormHt,dw,dh,"Advance");
  125.      h2 +=  margin + dw; 
  126. MAKE_BTN_ON_FORM(mainForm,donePBtn,h2,FormHt,dw,dh,"Done");
  127.     XtAddCallback(otherPBtn,XmNactivateCallback, toggleCB, NULL);
  128.     XtAddCallback(advancePBtn,XmNactivateCallback, advanceCB, NULL);
  129.     XtAddCallback(donePBtn,XmNactivateCallback, exit, NULL);
  130.     createDummyData(MAXITEMS, one, two); 
  131.     /* Calculate extents of this dummy data. */
  132.     imax = -100; imin = 100; 
  133.     for (i=0; i< MAXITEMS;i++)
  134.         {
  135.         ivalue  = one[i]; 
  136.         if (imax < ivalue) imax = ivalue;
  137.         if (imin > ivalue) imin = ivalue;
  138.         ivalue  = two[i]; 
  139.         if (imax < ivalue) imax = ivalue;
  140.         if (imin > ivalue) imin = ivalue;
  141.         }
  142.     imid = imin + 1; 
  143. #ifdef DEBUG_LIMITS
  144.     /* Tell the user where you are. */
  145.     printf("\n Min = %d  Mid = %d  Max = %d", imin,imid,imax); 
  146. #endif
  147.     /* Allocate the colors here. */
  148.     WhiteColor = str2pix("White", mainForm);  
  149.      BlackColor = str2pix("Black", mainForm); 
  150.      BlueColor = str2pix("Blue", mainForm);  
  151.      RedColor = str2pix("Red", mainForm); 
  152.      GreenColor = str2pix("Green", mainForm); 
  153.     sprintf(strName,"%d,%d",imax,imin);
  154.     /* Define and declare the Line Chart Widget. */
  155.     n = 0;
  156.     XtSetArg(wars[n], XmNheight, DispHt); n++;
  157.     XtSetArg(wars[n], XmNwidth, DispWd); n++;
  158.     XtSetArg(wars[n], XmNleftAttachment, XmATTACH_POSITION ); n++;
  159.     XtSetArg(wars[n], XmNrightAttachment, XmATTACH_POSITION ); n++;
  160.     XtSetArg(wars[n], XmNtopAttachment, XmATTACH_POSITION ); n++;
  161.     XtSetArg(wars[n], XmNbottomAttachment, XmATTACH_POSITION ); n++;
  162.     XtSetArg(wars[n], XmNleftPosition, 5 ); n++;
  163.     XtSetArg(wars[n], XmNrightPosition, 95); n++;
  164.     XtSetArg(wars[n], XmNtopPosition, 5 ); n++;
  165.     XtSetArg(wars[n], XmNbottomPosition, 75 ); n++;
  166.     XtSetArg(wars[n], XmNforeground, BlackColor); n++;
  167.     XtSetArg(wars[n], XmNbackground, WhiteColor); n++;
  168.     XtSetArg(wars[n], XtNitems, one); n++;
  169.     XtSetArg(wars[n], XtNauxItems, two); n++;
  170.     XtSetArg(wars[n], XtNitemCount, MAXITEMS); n++;
  171.     XtSetArg(wars[n], XtNmaxItemCount, MAXITEMS); n++;
  172.     XtSetArg(wars[n], XtNmaxValue, imax); n++;
  173.     XtSetArg(wars[n], XtNmidValue, imid); n++;
  174.     XtSetArg(wars[n], XtNminValue, imin); n++;
  175.     XtSetArg(wars[n], XtNzeroColor, BlueColor); n++;
  176.     XtSetArg(wars[n], XtNpositiveColor, BlueColor); n++;
  177.     XtSetArg(wars[n], XtNnegativeColor, RedColor); n++;
  178.     plotLChart = XtCreateWidget("LineChartType", 
  179.         XvlinechartWidgetClass, mainForm, wars, n);
  180.     imid = (imax + imin) / 2; 
  181. #ifdef DEBUG_LIMITS
  182.     printf("\n Min = %d  Mid = %d  Max = %d", imin,imid,imax); 
  183. #endif
  184.     /* Define and declare the Bar Chart Widget. */
  185.     n = 0;
  186.     XtSetArg(wars[n], XmNheight, DispHt); n++;
  187.     XtSetArg(wars[n], XmNwidth, DispWd); n++;
  188.     XtSetArg(wars[n], XmNforeground, BlackColor); n++;
  189.     XtSetArg(wars[n], XmNbackground, WhiteColor); n++;
  190.     XtSetArg(wars[n], XmNleftAttachment, XmATTACH_POSITION ); n++;
  191.     XtSetArg(wars[n], XmNrightAttachment, XmATTACH_POSITION ); n++;
  192.     XtSetArg(wars[n], XmNtopAttachment, XmATTACH_POSITION ); n++;
  193.     XtSetArg(wars[n], XmNbottomAttachment, XmATTACH_POSITION ); n++;
  194.     XtSetArg(wars[n], XmNleftPosition, 5 ); n++;
  195.     XtSetArg(wars[n], XmNrightPosition, 95); n++;
  196.     XtSetArg(wars[n], XmNtopPosition, 5 ); n++;
  197.     XtSetArg(wars[n], XmNbottomPosition, 75 ); n++;
  198.     XtSetArg(wars[n], XtNitems, one); n++;
  199.     XtSetArg(wars[n], XtNauxItems, two); n++;
  200.     XtSetArg(wars[n], XtNitemCount, MAXITEMS); n++;
  201.     XtSetArg(wars[n], XtNmaxItemCount, MAXITEMS); n++;
  202.     XtSetArg(wars[n], XtNmaxValue, imax); n++;
  203.     XtSetArg(wars[n], XtNmidValue, imid); n++;
  204.     XtSetArg(wars[n], XtNminValue, imin); n++;
  205.     XtSetArg(wars[n], XtNmaxShowValue, imax); n++;
  206.     XtSetArg(wars[n], XtNminShowValue, imin); n++;
  207.     XtSetArg(wars[n], XtNzeroColor, BlueColor); n++;
  208.     XtSetArg(wars[n], XtNpositiveColor, BlueColor); n++;
  209.     XtSetArg(wars[n], XtNnegativeColor, RedColor); n++;
  210.     plotBChart = XtCreateManagedWidget("BarChartDisplay", 
  211.         XvbarchartWidgetClass, mainForm, wars, n);
  212.     /* Show the widgets on the form and go into a loop */
  213.     XtManageChild(mainForm);
  214.     XtRealizeWidget(mainShell); 
  215.     XtMainLoop(); 
  216. }
  217. /* Terminate the application. */
  218. void exitCB()
  219. {
  220. exit(0); 
  221. }
  222. /* It's easier to use a flag here instead of calling XtIsManaged() on every 
  223. ** widget. This flag could index a circular list of Widgets and thus your 
  224. ** ToggleCB() function would go something like:
  225. **  ...
  226. **  XtUnmanage(YourList[ToggleFlag]); 
  227. **  ToggleFlag++; 
  228. **  if (ToggleFlag >= LengthOfList) ToggleFlag =0; 
  229. **  XtManage(YourList[ToggleFlag]); 
  230. **  ...
  231. ** where "YourList" is an array of widgets of length "LengthOfList". */
  232. static ToggleFlag = 1; 
  233. /* Callback for function to toggle the type of display. */
  234. int  toggleCB()
  235. {
  236. if (ToggleFlag) 
  237.     {
  238. #ifdef  DEBUG_SWAPPING_SCREENS
  239. printf("\n Debug statement goes here "); 
  240. #endif
  241.     XtUnmanageChild(plotBChart);
  242.     XtManageChild(plotLChart);
  243.     ToggleFlag = 0; 
  244.     }
  245.     else {
  246. #ifdef  DEBUG_SWAPPING_SCREENS
  247. printf("\n Debug statement goes here "); 
  248. #endif
  249.     XtManageChild(plotBChart);
  250.     XtUnmanageChild(plotLChart);
  251.     ToggleFlag = 1; 
  252.     }
  253. }
  254. /* Convenience to load in colors for the application. Returns pixel value 
  255. ** given the following inputs: char *spec;      color name
  256. **                         Widget w;        a widget pointer 
  257. */
  258. unsigned long str2pix(char *spec, Widget w)
  259. {
  260.     Colormap cmap;
  261.     XColor color_struct;        /* For this color     */
  262.     Display  *dpy;          /* Curent display     */
  263.     static void *ht = NULL;     /* hash table pointer */
  264.     /* Get Display  */
  265.     dpy = XtDisplay(w);
  266.     /*  Get color map */
  267.     cmap = XDefaultColormap(dpy, DefaultScreen(dpy));
  268.     /* Parse the color specification */
  269.     if (!XParseColor(dpy, cmap, spec, &color_struct)) 
  270.         {
  271.         printf("Invalid color name (%s)\n",spec);
  272.         exit(1);
  273.         }
  274.     /* Try to allocate the color */
  275.     if (!XAllocColor(dpy, cmap, &color_struct)) 
  276.         {
  277.         printf("Cannot allocate color in colormap\n");
  278.         exit(1);
  279.         }
  280.     /* Return the allocated color */
  281.     return(color_struct.pixel);
  282. }
  283. /* Cycle the data thru itself when button is pressed on "Advance" */
  284. int  advanceCB()
  285. {
  286. if (siCounter <  1) siCounter = MAXITEMS;
  287. #ifdef DEBUG_SI_COUNTER
  288. printf("\n siCounter = %d", siCounter); 
  289. #endif
  290. siCounter--; 
  291. XvBarChartAddItem(plotLChart, one[siCounter]); 
  292. XvBarChartAddItem(plotBChart, two[siCounter]); 
  293. }
  294. /* Create some data in an array. */
  295. void createDummyData(int count, int *oneptr, int *twoptr)
  296. {
  297. int i; 
  298. for (i = 0; i < count/2; i++)
  299.     {
  300.     oneptr[i] = (i * 2) + 10; 
  301.     twoptr[i] = (i * 3) + 5;
  302.     }
  303. for (i = count/2; i < count; i++)
  304.     {
  305.     oneptr[i] = (i * 2) - 10; 
  306.     twoptr[i] = (i * 3) - 5;
  307.     }
  308. }
  309.  
  310.