Hello,

First off, thanks to Alexander for his suggestion. Following his advice,
I am posting a patch for vanilla SciPlot-1.36 that adds double buffer
and very basic UIL support. Please take the patch with a grain of
salt because I have very little experience in Motif programming. Hope it
can be improved enough to make it into Xlt :)

Regards,
Andrei Romanenko
Departamento de Engenharia Qu�mica
Faculdade de Ci�ncias e Tecnologia
Universidade de Coimbra
Pinhal de Marrocos
P�lo II
3030 Coimbra

phone: +351-239-798776
fax:   +351-239-798703
e-mail: [EMAIL PROTECTED]
diff -N -u SciPlot-1.36/Imakefile SciPlot/Imakefile
--- SciPlot-1.36/Imakefile      Thu Sep  5 03:32:58 1996
+++ SciPlot/Imakefile   Wed Feb 28 10:29:48 2001
@@ -2,9 +2,9 @@
 
 #ifdef LinuxArchitecture
     CC = gcc
-    EXTRA_DEFINES = -g -Wall
+    EXTRA_DEFINES = -g -Wall -I/usr/local/dt/include -DMOTIF
     CDEBUGFLAGS = -m486
-    LESSTIF = -L/home/rob/src/lesstif/libXm
+    LESSTIF = -L/usr/local/dt/lib
     HDOC = ~/public_html/hdoc
 #endif
 #ifdef AIXArchitecture
@@ -17,7 +17,7 @@
     CC = cc -std1
 #endif
 
-MOTIF = $(LESSTIF) -lXm
+MOTIF = $(LESSTIF) -lXm -lMrm
 
 MOTIFDEPS = $(DEPXMLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
 MOTIFLIBS = $(MOTIF) $(XMULIB) $(XTOOLLIB) $(XLIB)
diff -N -u SciPlot-1.36/SciPlot.c SciPlot/SciPlot.c
--- SciPlot-1.36/SciPlot.c      Thu Sep  5 03:32:58 1996
+++ SciPlot/SciPlot.c   Mon Mar  5 14:03:15 2001
@@ -20,10 +20,16 @@
  *
  * Author: Rob McMullen <[EMAIL PROTECTED]>
  *         http://www.ae.utexas.edu/~rwmcm
+ * 
+ * Changes: added double buffering (Andrei Romanenko <[EMAIL PROTECTED]>)
+ *          added basic UIL support (Andrei Romanenko <[EMAIL PROTECTED]>)         
  */
 
 #include <X11/IntrinsicP.h>
 #include <X11/StringDefs.h>
+#ifdef MOTIF
+#include <Mrm/MrmAppl.h>
+#endif
 
 #include <stdio.h>
 
@@ -96,6 +102,8 @@
     offset(YOrigin), XtRImmediate, (XtPointer) False},
   {XtNyNumbersHorizontal, XtCBoolean, XtRBoolean, sizeof(Boolean),
     offset(YNumHorz), XtRImmediate, (XtPointer) True},
+  {XtNdoubleBuffer, XtCBoolean, XtRBoolean, sizeof(Boolean),
+    offset(doublebufferflag), XtRImmediate, (XtPointer) False},
 };
 
 static SciPlotFontDesc font_desc_table[] =
@@ -133,8 +141,6 @@
 static int FontStore();
 static int FontnumReplace();
 
-
-
 SciPlotClassRec sciplotClassRec =
 {
   {
@@ -239,6 +245,22 @@
   new->plot.titleFont = FontStore(new, new->plot.TitleFont);
   new->plot.labelFont = FontStore(new, new->plot.LabelFont);
   new->plot.axisFont = FontStore(new, new->plot.AxisFont);
+
+/*
+  if(new->plot.doublebufferflag== TRUE) {
+     new->plot.buffer = XCreatePixmap(XtDisplay(new), 
+                                      DefaultRootWindow(XtDisplay(new)),
+                                      new->core.width,
+                                      new->core.height,
+                                      new->core.depth);
+     if(new->plot.buffer == 0) {
+        new->plot.doublebufferflag = FALSE;
+        XtError("Couldn't allocate memory for double buffering");
+     }
+  } else {
+     new->plot.buffer= 0;
+  } 
+  */
 }
 
 static void
@@ -266,6 +288,11 @@
   values.foreground = colorsave;
   values.line_style = LineOnOffDash;
   new->plot.dashGC = XCreateGC(XtDisplay(new),XtWindow(new), mask, &values);
+
+  values.foreground = new->core.background_pixel;
+  values.background = new->core.background_pixel;
+  mask = GCForeground | GCBackground;
+  new->plot.clearGC = XtGetGC((Widget)new, mask, &values);
 }
 
 static void
@@ -278,6 +305,25 @@
 #undef superclass
 
   GCInitialize(w);
+
+  if(w->plot.doublebufferflag== TRUE) {
+     w->plot.buffer = XCreatePixmap(XtDisplay(w), 
+                                      DefaultRootWindow(XtDisplay(w)),
+                                      w->core.width,
+                                      w->core.height,
+                                      w->core.depth);
+     if(w->plot.buffer == 0) {
+        w->plot.doublebufferflag = FALSE;
+        XtError("Couldn't allocate memory for double buffering");
+     } else {
+        XFillRectangle(XtDisplay(w), w->plot.buffer, 
+                       w->plot.clearGC,
+                       0, 0,
+                       w->core.width, w->core.height);
+     }
+  } else {
+     w->plot.buffer= 0;
+  } 
 }
 
 static void
@@ -289,6 +335,7 @@
 
   XFreeGC(XtDisplay(w), w->plot.defaultGC);
   XFreeGC(XtDisplay(w), w->plot.dashGC);
+  XFreeGC(XtDisplay(w), w->plot.clearGC);
   XtFree((char *) w->plot.xlabel);
   XtFree((char *) w->plot.ylabel);
   XtFree((char *) w->plot.plotTitle);
@@ -313,6 +360,8 @@
 
   EraseAll(w);
   XtFree((char *) w->plot.drawlist);
+  if(w->plot.buffer)
+     XFreePixmap(XtDisplay(w), w->plot.buffer);
 }
 
 static Boolean
@@ -357,6 +406,8 @@
     redisplay = TRUE;
   else if (current->plot.Monochrome != new->plot.Monochrome)
     redisplay = TRUE;
+  else if(current->plot.doublebufferflag != new->plot.doublebufferflag)
+    redisplay = TRUE;
   
   if (new->plot.TransientXLabel) {
     if (current->plot.TransientXLabel != new->plot.TransientXLabel ||
@@ -401,6 +452,30 @@
     redisplay = TRUE;
     FontnumReplace(new, new->plot.labelFont, new->plot.LabelFont);
   }
+  if(current->plot.doublebufferflag != new->plot.doublebufferflag) {
+     switch(new->plot.doublebufferflag) {
+        case TRUE:
+                   new->plot.buffer = XCreatePixmap(XtDisplay(new), 
+                                             DefaultRootWindow(XtDisplay(new)),
+                                             new->core.width,
+                                             new->core.height,
+                                             new->core.depth);
+                   if(new->plot.buffer == 0) {
+                      new->plot.doublebufferflag = FALSE;
+                      XtError("Couldn't allocate memory for double buffering");
+                      break;
+                   }
+                   XFillRectangle(XtDisplay(new), new->plot.buffer, 
+                                  new->plot.clearGC,
+                                  0, 0,
+                                  new->core.width, new->core.height);
+                   break;
+       case FALSE:
+                   XFreePixmap(XtDisplay(new), new->plot.buffer);
+                   new->plot.buffer = 0;
+                   break;
+     }
+  }
 
   new->plot.update = redisplay;
 
@@ -427,17 +502,30 @@
 
 
 static void
-Redisplay(SciPlotWidget w)
+Redisplay(SciPlotWidget w, XExposeEvent *event, Region region)
 {
   if (!XtIsRealized((Widget)w))
     return;
   
-  if (w->plot.update) {
-    Resize(w);
-    w->plot.update = FALSE;
-  }
-  else {
-    ItemDrawAll(w);
+  if(w->plot.doublebufferflag == FALSE) {
+     if (w->plot.update) {
+       Resize(w);
+       w->plot.update = FALSE;
+     }
+     else {
+       ItemDrawAll(w);
+     }
+  } else {
+     if(w->plot.buffer) {
+     /* Partial update from the double buffer */
+        XCopyArea(XtDisplay(w),
+                  w->plot.buffer,
+                  XtWindow(w),
+                  w->plot.defaultGC,
+                  event->x, event->y,
+                  event->width, event->height,
+                  event->x, event->y);
+     }
   }
 }
 
@@ -447,6 +535,16 @@
   if (!XtIsRealized((Widget)w))
     return;
   
+  if(w->plot.buffer) {
+     XtWarning("Resize request for the double buffer has arrived");
+     XFreePixmap(XtDisplay(w), w->plot.buffer);
+     w->plot.buffer = XCreatePixmap(XtDisplay(w),
+                                    DefaultRootWindow(XtDisplay(w)),
+                                    w->core.width,
+                                    w->core.height,
+                                    w->core.depth);
+  }
+
   EraseAll(w);
   ComputeAll(w);
   DrawAll(w);
@@ -1177,11 +1275,15 @@
   XPoint point[8];
   XSegment seg;
   XRectangle rect;
+  Drawable canvas;
   int i;
   GC gc;
 
   if (!XtIsRealized((Widget) w))
     return;
+  
+  canvas = (w->plot.doublebufferflag && w->plot.buffer)?
+                                           w->plot.buffer:XtWindow(w);
   if ((item->type > SciPlotStartTextTypes) && (item->type < SciPlotEndTextTypes))
     gc = ItemGetFontGC(w, item);
   else
@@ -1194,23 +1296,23 @@
     seg.y1 = (short) item->kind.line.y1;
     seg.x2 = (short) item->kind.line.x2;
     seg.y2 = (short) item->kind.line.y2;
-    XDrawSegments(XtDisplay(w), XtWindow(w), gc,
+    XDrawSegments(XtDisplay(w), canvas, gc,
       &seg, 1);
     break;
   case SciPlotRect:
-    XDrawRectangle(XtDisplay(w), XtWindow(w), gc,
+    XDrawRectangle(XtDisplay(w), canvas, gc,
       (int) (item->kind.rect.x),
       (int) (item->kind.rect.y),
       (unsigned int) (item->kind.rect.w),
       (unsigned int) (item->kind.rect.h));
     break;
   case SciPlotFRect:
-    XFillRectangle(XtDisplay(w), XtWindow(w), gc,
+    XFillRectangle(XtDisplay(w), canvas, gc,
       (int) (item->kind.rect.x),
       (int) (item->kind.rect.y),
       (unsigned int) (item->kind.rect.w),
       (unsigned int) (item->kind.rect.h));
-    XDrawRectangle(XtDisplay(w), XtWindow(w), gc,
+    XDrawRectangle(XtDisplay(w), canvas, gc,
       (int) (item->kind.rect.x),
       (int) (item->kind.rect.y),
       (unsigned int) (item->kind.rect.w),
@@ -1225,7 +1327,7 @@
     }
     point[i].x = (int) item->kind.poly.x[0];
     point[i].y = (int) item->kind.poly.y[0];
-    XDrawLines(XtDisplay(w), XtWindow(w), gc,
+    XDrawLines(XtDisplay(w), canvas, gc,
       point, i + 1, CoordModeOrigin);
     break;
   case SciPlotFPoly:
@@ -1237,13 +1339,13 @@
     }
     point[i].x = (int) item->kind.poly.x[0];
     point[i].y = (int) item->kind.poly.y[0];
-    XFillPolygon(XtDisplay(w), XtWindow(w), gc,
+    XFillPolygon(XtDisplay(w), canvas, gc,
       point, i + 1, Complex, CoordModeOrigin);
-    XDrawLines(XtDisplay(w), XtWindow(w), gc,
+    XDrawLines(XtDisplay(w), canvas, gc,
       point, i + 1, CoordModeOrigin);
     break;
   case SciPlotCircle:
-    XDrawArc(XtDisplay(w), XtWindow(w), gc,
+    XDrawArc(XtDisplay(w), canvas, gc,
       (int) (item->kind.circ.x - item->kind.circ.r),
       (int) (item->kind.circ.y - item->kind.circ.r),
       (unsigned int) (item->kind.circ.r * 2),
@@ -1251,7 +1353,7 @@
       0 * 64, 360 * 64);
     break;
   case SciPlotFCircle:
-    XFillArc(XtDisplay(w), XtWindow(w), gc,
+    XFillArc(XtDisplay(w), canvas, gc,
       (int) (item->kind.circ.x - item->kind.circ.r),
       (int) (item->kind.circ.y - item->kind.circ.r),
       (unsigned int) (item->kind.circ.r * 2),
@@ -1259,13 +1361,13 @@
       0 * 64, 360 * 64);
     break;
   case SciPlotText:
-    XDrawString(XtDisplay(w), XtWindow(w), gc,
+    XDrawString(XtDisplay(w), canvas, gc,
       (int) (item->kind.text.x), (int) (item->kind.text.y),
       item->kind.text.text,
       (int) item->kind.text.length);
     break;
   case SciPlotVText:
-    XDrawVString(XtDisplay(w), XtWindow(w), gc,
+    XDrawVString(XtDisplay(w), canvas, gc,
       (int) (item->kind.text.x), (int) (item->kind.text.y),
       item->kind.text.text,
       (int) item->kind.text.length,
@@ -1689,8 +1791,16 @@
 EraseAll (SciPlotWidget w)
 {
   EraseAllItems(w);
-  if (XtIsRealized((Widget) w))
-    XClearWindow(XtDisplay(w), XtWindow(w));
+  if (XtIsRealized((Widget) w)) {
+     if(w->plot.buffer && w->plot.doublebufferflag) {
+         XFillRectangle(XtDisplay(w), w->plot.buffer, 
+                        w->plot.clearGC,
+                        0, 0,
+                        w->core.width, w->core.height);
+     } else {
+     XClearWindow(XtDisplay(w), XtWindow(w));
+     }
+  }     
 }
 
 static SciPlotItem *
@@ -3388,6 +3498,15 @@
     DrawLegend(w);
     DrawPolarPlot(w);
   }
+  if(XtIsRealized((Widget)w) && w->plot.doublebufferflag && w->plot.buffer) {
+     XCopyArea(XtDisplay(w),
+               w->plot.buffer,
+               XtWindow(w),
+               w->plot.defaultGC,
+               0, 0,
+               w->core.width, w->core.height,
+               0, 0);
+  }
 }
 
 static Boolean 
@@ -3399,6 +3518,15 @@
   EraseClassItems(w, SciPlotDrawingLine);
   EraseAllItems(w);
   DrawAll(w);
+  if(XtIsRealized((Widget)w) && w->plot.doublebufferflag && w->plot.buffer){
+     XCopyArea(XtDisplay(w),
+               w->plot.buffer,
+               XtWindow(w),
+               w->plot.defaultGC,
+               0, 0,
+               w->core.width, w->core.height,
+               0, 0);
+  }
   
   return range_check;
 }
@@ -3809,3 +3937,19 @@
   w = (SciPlotWidget) wi;
   return DrawQuick(w);
 }
+
+#ifdef MOTIF
+/* Convenience routines for UIL */
+
+Widget SciPlotCreate(Widget parent, char *name, Arg *arglist, int nargs)
+{
+    return(XtCreateManagedWidget (name, sciplotWidgetClass, parent, arglist, nargs));
+}
+int SciPlotMrmInitialize()
+{
+    return(MrmRegisterClass (MrmwcUnknown, "SciPlot" , "SciPlotCreate",
+               SciPlotCreate,
+               (WidgetClass)&sciplotClassRec));
+}
+#endif /*MOTIF*/
+
diff -N -u SciPlot-1.36/SciPlot.h SciPlot/SciPlot.h
--- SciPlot-1.36/SciPlot.h      Thu Sep  5 03:32:58 1996
+++ SciPlot/SciPlot.h   Wed Feb 28 10:23:34 2001
@@ -82,6 +82,7 @@
 #define XtNlabelFont   "labelFont"
 #define XtNaxisFont    "axisFont"
 #define XtNyNumbersHorizontal  "yNumbersHorizontal"
+#define XtNdoubleBuffer        "DoubleBuffer"
 
 #define XtPOLAR                0
 #define XtCARTESIAN    1
@@ -182,6 +183,8 @@
 void SciPlotUpdate P_((Widget wi));
 Boolean SciPlotQuickUpdate P_((Widget wi));
 
+Widget SciPlotCreate(Widget parent, char *name, Arg *arglist, int nargs);
+int SciPlotMrmInitialize();
 #undef P_
 
 #ifdef __cplusplus
diff -N -u SciPlot-1.36/SciPlot.uil SciPlot/SciPlot.uil
--- SciPlot-1.36/SciPlot.uil    Thu Jan  1 01:00:00 1970
+++ SciPlot/SciPlot.uil Mon Feb 26 17:31:17 2001
@@ -0,0 +1,78 @@
+value
+   XtNchartType:       private argument ('chartType', integer);
+   XtNdegrees: private argument ('degrees', boolean);
+   XtNdefaultMarkerSize: private argument ('defaultMarkerSize', integer);
+   XtNdrawMajor:       private argument ('drawMajor', boolean);
+   XtNdrawMajorTics:   private argument ('drawMajorTics', boolean);
+   XtNdrawMinor:       private argument ('drawMinor', boolean);
+   XtNdrawMinorTics:   private argument ('drawMinorTics', boolean);
+   XtNxAutoScale:      private argument ('xAutoScale', boolean);
+   XtNyAutoScale:      private argument ('yAutoScale', boolean);
+   XtNxAxisNumbers:    private argument ('xAxisNumbers', boolean);
+   XtNyAxisNumbers:    private argument ('yAxisNumbers', boolean);
+   XtNxLog     :       private argument ('xLog', boolean);
+   XtNyLog     :       private argument ('yLog', boolean);
+   XtNxOrigin: private argument ('xOrigin', boolean);
+   XtNyOrigin: private argument ('yOrigin', boolean);
+   XtNxLabel:  private argument ('xLabel', string);
+   XtNyLabel:  private argument ('yLabel', string);
+   XtNplotTitle:       private argument ('plotTitle', string);
+   XtNmargin:  private argument ('margin', integer);
+   XtNmonochrome:      private argument ('monochrome', boolean);
+   XtNtitleMargin:     private argument ('titleMargin', integer);
+   XtNshowLegend:      private argument ('showLegend', boolean);
+   XtNshowTitle:       private argument ('showTitle', boolean);
+   XtNshowXLabel:      private argument ('showXLabel', boolean);
+   XtNshowYLabel:      private argument ('showYLabel', boolean);
+   XtNlegendLineSize:  private argument ('legendLineSize', integer);
+   XtNlegendMargin:    private argument ('legendMargin', integer);
+   XtNlegendThroughPlot:       private argument ('legendThroughPlot', boolean);
+   XtNtitleFont:       private argument ('titleFont', integer);
+   XtNlabelFont:       private argument ('labelFont', integer);
+   XtNaxisFont :private argument ('axisFont', integer);
+   XtNyNumbersHorizontal:      private argument ('yNumbersHorizontal', boolean);
+   XtNdoubleBuffer:    private argument ('DoubleBuffer', boolean);
+
+value
+   XtPOLAR :                 0;
+   XtCARTESIAN :        1;
+   XtMARKER_NONE :             0;
+   XtMARKER_CIRCLE :           1;
+   XtMARKER_SQUARE :           2;
+   XtMARKER_UTRIANGLE :        3;
+   XtMARKER_DTRIANGLE :        4;
+   XtMARKER_LTRIANGLE :        5;
+   XtMARKER_RTRIANGLE :        6;
+   XtMARKER_DIAMOND :   7;
+   XtMARKER_HOURGLASS: 8;
+   XtMARKER_BOWTIE :      9;
+   XtMARKER_FCIRCLE :   10;
+   XtMARKER_FSQUARE :   11;
+   XtMARKER_FUTRIANGLE:        12;
+   XtMARKER_FDTRIANGLE:        13;
+   XtMARKER_FLTRIANGLE:        14;
+   XtMARKER_FRTRIANGLE:        15;
+   XtMARKER_FDIAMOND   :  16;
+   XtMARKER_FHOURGLASS:        17;
+   XtMARKER_FBOWTIE:      18;
+   XtMARKER_DOT:                  19;
+   XtFONT_SIZE_MASK:      255;
+   XtFONT_SIZE_DEFAULT:        12;
+   XtFONT_NAME_MASK:      3840;
+   XtFONT_TIMES        :          000;
+   XtFONT_COURIER      :          256;
+   XtFONT_HELVETICA:      512;
+   XtFONT_LUCIDA       :          768;
+   XtFONT_LUCIDASANS:  1024;
+   XtFONT_NCSCHOOLBOOK:        1280;
+   XtFONT_NAME_DEFAULT:        XtFONT_TIMES;
+   XtFONT_ATTRIBUTE_MASK:      61440;
+   XtFONT_BOLD:                   4096;
+   XtFONT_ITALIC       :          8192;
+   XtFONT_BOLD_ITALIC: 12288;
+   XtFONT_ATTRIBUTE_DEFAULT: 0;
+   XtLINE_NONE :        0;
+   XtLINE_SOLID:             1;
+   XtLINE_DOTTED:            2;
+   XtLINE_WIDEDOT:        3;
+   XtLINE_USERDASH:       4;
diff -N -u SciPlot-1.36/SciPlotP.h SciPlot/SciPlotP.h
--- SciPlot-1.36/SciPlotP.h     Thu Sep  5 03:32:58 1996
+++ SciPlot/SciPlotP.h  Mon Feb 26 11:44:16 2001
@@ -241,11 +241,15 @@
 
   GC defaultGC;
   GC dashGC;
+  GC clearGC;
   Colormap cmap;
   Pixel *colors;
   int num_colors;
   SciPlotFont *fonts;
   int num_fonts;
+  
+  Pixmap buffer;
+  Boolean doublebufferflag;
 
   int alloc_plotlist;
   int num_plotlist;
diff -N -u SciPlot-1.36/example.uil SciPlot/example.uil
--- SciPlot-1.36/example.uil    Thu Jan  1 01:00:00 1970
+++ SciPlot/example.uil Mon Mar  5 14:15:14 2001
@@ -0,0 +1,33 @@
+module hellosciplot
+    version = 'v1.0'
+    names = case_sensitive
+
+include file 'SciPlot.uil';
+
+procedure 
+    SciPlotCreate();
+
+! Please add the main window to put "plot1"
+!
+
+object 
+   plot1 : user_defined procedure SciPlotCreate() {
+      arguments {
+!         XmNheight = 500 ;
+!         XmNwidth = 500 ;
+         XtNshowLegend = false;
+         XtNshowTitle = false;
+         XtNshowXLabel = false;
+         XtNshowYLabel = false;
+         XtNxAutoScale = true;
+         XtNyAutoScale = false;
+         XtNdoubleBuffer = true;
+         XtNaxisFont = 20;
+!         XtNplotTitle = "Demo of Plot Widget" ;
+!         XtNxLabel = "X Axis (units)" ;
+!         XtNyLabel = "Y Axis (units)" ;
+!         XtNchartType = XtPOLAR ;
+         XtNdegrees = true ;
+      };
+
+end module;
diff -N -u SciPlot-1.36/realtime.c SciPlot/realtime.c
--- SciPlot-1.36/realtime.c     Thu Sep  5 03:32:58 1996
+++ SciPlot/realtime.c  Mon Mar  5 13:48:37 2001
@@ -38,6 +38,16 @@
 {
   Widget plot = (Widget) client_data;
   int index;
+  static int count =0;
+  Boolean state;
+
+  XtVaGetValues(plot, XtNdoubleBuffer, &state, NULL);
+
+  if((count > 10) && (state != TRUE)) {
+          printf("Double\n");
+          state = TRUE;
+          XtVaSetValues(plot, XtNdoubleBuffer, state, NULL);
+  }
 
   index=rand()%10;
   if (index>0) ydata[index]+=1.0;
@@ -45,7 +55,7 @@
   if (SciPlotQuickUpdate(plot)) {
       SciPlotUpdate(plot);
   }
-  
+  count++; 
   XtAppAddTimeOut(app_con,500,Update,plot);
 }
 

Reply via email to