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);
}