283 lines
8.7 KiB
C
283 lines
8.7 KiB
C
|
|
||
|
/* $XConsortium: Graph.c,v 1.2 88/10/25 17:40:25 swick Exp $ */
|
||
|
/* Copyright Massachusetts Institute of Technology 1987, 1988 */
|
||
|
|
||
|
#include <X11/IntrinsicP.h>
|
||
|
#include <X11/StringDefs.h>
|
||
|
#include "GraphP.h"
|
||
|
|
||
|
|
||
|
#include <stdio.h>
|
||
|
|
||
|
/* ---- Forward declarations ---- */
|
||
|
|
||
|
|
||
|
static void Initialize(Widget request, Widget new,
|
||
|
ArgList args, Cardinal *num_args);
|
||
|
static void Destroy(Widget w);
|
||
|
static void Redisplay(Widget w, XEvent *event, Region region);
|
||
|
static void Resize(Widget w);
|
||
|
static void InputAction(Widget w, XEvent *event,
|
||
|
String *params,Cardinal *num_params);
|
||
|
static Boolean SetValues(Widget current, Widget request, Widget new,
|
||
|
ArgList args, Cardinal *num_args);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ---- Private data ---- */
|
||
|
|
||
|
|
||
|
static XtResource resources[] = {
|
||
|
#define offset(field) XtOffset(GraphWidget, graph.field)
|
||
|
#define coffset(field) XtOffset(Widget, core.field)
|
||
|
/* {name, class, type, size, offset, default_type, default_addr}, */
|
||
|
{ XtNcallback, XtCCallback, XtRCallback, (Cardinal)sizeof(XtCallbackList),
|
||
|
offset(input_callback), XtRCallback, NULL },
|
||
|
{ XtNdimBackground, XtCBackground, XtRPixel, (Cardinal)sizeof(Pixel),
|
||
|
offset(dimBackground), XtRString, "XtDefaultBackground" },
|
||
|
{ XtNexposeCallback, XtCCallback, XtRCallback,
|
||
|
(Cardinal)sizeof(XtCallbackList),
|
||
|
offset(expose_callback), XtRCallback, NULL },
|
||
|
{ XtNfont, XtCFont, XtRFontStruct, (Cardinal)sizeof(XFontStruct*),
|
||
|
offset(font), XtRString, XtDefaultFont },
|
||
|
{ XtNgraphColour1, XtCForeground, XtRPixel, (Cardinal)sizeof(Pixel),
|
||
|
offset(graphColour1), XtRString, "XtDefaultForeground" },
|
||
|
{ XtNgraphColour2, XtCForeground, XtRPixel, (Cardinal)sizeof(Pixel),
|
||
|
offset(graphColour2), XtRString, "XtDefaultForeground" },
|
||
|
{ XtNgraphColour3, XtCForeground, XtRPixel, (Cardinal)sizeof(Pixel),
|
||
|
offset(graphColour3), XtRString, "XtDefaultForeground" },
|
||
|
{ XtNgraphColour4, XtCForeground, XtRPixel, (Cardinal)sizeof(Pixel),
|
||
|
offset(graphColour4), XtRString, "XtDefaultForeground" },
|
||
|
{ XtNheight, XtCHeight, XtRDimension, (Cardinal)sizeof(Dimension),
|
||
|
coffset(height), XtRImmediate, (caddr_t)1},
|
||
|
{ XtNwidth, XtCWidth, XtRDimension, (Cardinal)sizeof(Dimension),
|
||
|
coffset(width), XtRImmediate, (caddr_t)1},
|
||
|
{ XtNresizeCallback, XtCCallback, XtRCallback,
|
||
|
(Cardinal)sizeof(XtCallbackList),
|
||
|
offset(resize_callback), XtRCallback, NULL },
|
||
|
#undef offset
|
||
|
#undef coffset
|
||
|
};
|
||
|
|
||
|
|
||
|
static XtActionsRec actions[] =
|
||
|
{
|
||
|
/* {name, procedure}, */
|
||
|
{"input", InputAction},
|
||
|
};
|
||
|
|
||
|
|
||
|
static char translations[] =
|
||
|
"<Key>: input() \n\
|
||
|
<BtnDown>: input() \
|
||
|
";
|
||
|
|
||
|
|
||
|
GraphClassRec graphClassRec = {
|
||
|
{ /* core fields initial values */
|
||
|
/* superclass */ (WidgetClass) &simpleClassRec,
|
||
|
/* class_name */ "Graph",
|
||
|
/* widget_size */ (Cardinal)sizeof(GraphRec),
|
||
|
/* class_initialize */ NULL,
|
||
|
/* class_part_initialize */ NULL,
|
||
|
/* class_inited */ FALSE,
|
||
|
/* initialize */ Initialize,
|
||
|
/* initialize_hook */ NULL,
|
||
|
/* realize */ XtInheritRealize,
|
||
|
/* actions */ actions,
|
||
|
/* num_actions */ XtNumber(actions),
|
||
|
/* resources */ resources,
|
||
|
/* num_resources */ XtNumber(resources),
|
||
|
/* xrm_class */ NULLQUARK,
|
||
|
/* compress_motion */ TRUE,
|
||
|
/* compress_exposure */ XtExposeCompressMaximal,
|
||
|
/* compress_enterleave */ TRUE,
|
||
|
/* visible_interest */ FALSE,
|
||
|
/* destroy */ Destroy,
|
||
|
/* resize */ Resize,
|
||
|
/* expose */ Redisplay,
|
||
|
/* set_values */ SetValues,
|
||
|
/* set_values_hook */ NULL,
|
||
|
/* set_values_almost */ XtInheritSetValuesAlmost,
|
||
|
/* get_values_hook */ NULL,
|
||
|
/* accept_focus */ NULL,
|
||
|
/* version */ XtVersion,
|
||
|
/* callback_private */ NULL,
|
||
|
/* tm_table */ translations,
|
||
|
/* query_geometry */ XtInheritQueryGeometry,
|
||
|
/* display_accelerator */ XtInheritDisplayAccelerator,
|
||
|
/* extension */ NULL
|
||
|
},
|
||
|
{ /* Simple class initial values */
|
||
|
/* change_sensitive */ XtInheritChangeSensitive
|
||
|
},
|
||
|
{ /* Graph class initial values */
|
||
|
/* empty */ 0
|
||
|
}
|
||
|
};
|
||
|
|
||
|
WidgetClass graphWidgetClass = (WidgetClass)&graphClassRec;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ---- Private procedures ---- */
|
||
|
|
||
|
|
||
|
static void Initialize(Widget request, Widget new,
|
||
|
ArgList args, Cardinal *num_args)
|
||
|
{ GraphWidget gw = (GraphWidget)new;
|
||
|
unsigned long xGCMask;
|
||
|
XGCValues xGCValues;
|
||
|
Display *display;
|
||
|
int screen;
|
||
|
|
||
|
display = XtDisplay(request);
|
||
|
screen = DefaultScreen(display);
|
||
|
|
||
|
if (DisplayPlanes(display,screen)==1)
|
||
|
{ /* We are on a one-plane monochrome display.
|
||
|
Use dashes to make lines distinguishable.
|
||
|
*/
|
||
|
xGCMask = GCForeground | GCBackground | GCLineStyle;
|
||
|
xGCValues.foreground = BlackPixel(display,screen);
|
||
|
xGCValues.background = WhitePixel(display,screen);
|
||
|
xGCValues.line_style = LineSolid;
|
||
|
gw->graph.graphGC1 = XtGetGC((Widget) gw, xGCMask, &xGCValues);
|
||
|
|
||
|
xGCMask = GCForeground | GCBackground | GCLineStyle | GCDashList;
|
||
|
xGCValues.foreground = BlackPixel(display,screen);
|
||
|
xGCValues.background = WhitePixel(display,screen);
|
||
|
xGCValues.line_style = LineOnOffDash;
|
||
|
xGCValues.dashes = 1;
|
||
|
gw->graph.graphGC2 = XtGetGC((Widget) gw, xGCMask, &xGCValues);
|
||
|
|
||
|
xGCMask = GCForeground | GCBackground | GCLineStyle | GCDashList;
|
||
|
xGCValues.foreground = BlackPixel(display,screen);
|
||
|
xGCValues.background = WhitePixel(display,screen);
|
||
|
xGCValues.line_style = LineOnOffDash;
|
||
|
xGCValues.dashes = 2;
|
||
|
gw->graph.graphGC3 = XtGetGC((Widget) gw, xGCMask, &xGCValues);
|
||
|
|
||
|
xGCMask = GCForeground | GCBackground | GCLineStyle | GCDashList;
|
||
|
xGCValues.foreground = BlackPixel(display,screen);
|
||
|
xGCValues.background = WhitePixel(display,screen);
|
||
|
xGCValues.line_style = LineOnOffDash;
|
||
|
xGCValues.dashes = 4;
|
||
|
gw->graph.graphGC4 = XtGetGC((Widget) gw, xGCMask, &xGCValues);
|
||
|
|
||
|
gw->graph.graphColour1 = BlackPixel(display,screen);
|
||
|
gw->graph.graphColour2 = BlackPixel(display,screen);
|
||
|
gw->graph.graphColour3 = BlackPixel(display,screen);
|
||
|
gw->graph.graphColour4 = BlackPixel(display,screen);
|
||
|
}
|
||
|
else
|
||
|
{ /* Some sort of multi-plane display.
|
||
|
*/
|
||
|
xGCMask = GCForeground | GCBackground;
|
||
|
xGCValues.background = gw->core.background_pixel;
|
||
|
|
||
|
xGCValues.foreground = gw->graph.graphColour1;
|
||
|
gw->graph.graphGC1 = XtGetGC((Widget) gw, xGCMask, &xGCValues);
|
||
|
|
||
|
xGCValues.foreground = gw->graph.graphColour2;
|
||
|
gw->graph.graphGC2 = XtGetGC((Widget) gw, xGCMask, &xGCValues);
|
||
|
|
||
|
xGCValues.foreground = gw->graph.graphColour3;
|
||
|
gw->graph.graphGC3 = XtGetGC((Widget) gw, xGCMask, &xGCValues);
|
||
|
|
||
|
xGCValues.foreground = gw->graph.graphColour4;
|
||
|
gw->graph.graphGC4 = XtGetGC((Widget) gw, xGCMask, &xGCValues);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static void Destroy (Widget w)
|
||
|
{ GraphWidget gw = (GraphWidget) w;
|
||
|
|
||
|
XtDestroyGC(gw->graph.graphGC1);
|
||
|
XtDestroyGC(gw->graph.graphGC2);
|
||
|
XtDestroyGC(gw->graph.graphGC3);
|
||
|
XtDestroyGC(gw->graph.graphGC4);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void Redisplay(Widget w, XEvent *event, Region region)
|
||
|
{ XtCallCallbacks(w, XtNexposeCallback, (caddr_t)region);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void Resize(Widget w)
|
||
|
{ XtCallCallbacks(w, XtNresizeCallback, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void InputAction(Widget w, XEvent *event,
|
||
|
String *params,Cardinal *num_params)
|
||
|
{ XtCallCallbacks(w, XtNcallback, (caddr_t)event);
|
||
|
}
|
||
|
|
||
|
|
||
|
static Boolean SetValues(Widget current, Widget request, Widget new,
|
||
|
ArgList args, Cardinal *num_args)
|
||
|
{ GraphWidget g_old = (GraphWidget) current;
|
||
|
GraphWidget g_new = (GraphWidget) new;
|
||
|
|
||
|
if (DisplayPlanes(XtDisplay(new), DefaultScreen(XtDisplay(new))) == 1 ||
|
||
|
!XtIsRealized(new))
|
||
|
{ /* Silly to change, or can't change.
|
||
|
Don't generate an expose.
|
||
|
*/
|
||
|
return(False);
|
||
|
}
|
||
|
else
|
||
|
{ if (g_old->graph.graphColour1 != g_new->graph.graphColour1)
|
||
|
XSetForeground(XtDisplay(new),
|
||
|
g_new->graph.graphGC1,
|
||
|
g_new->graph.graphColour1);
|
||
|
|
||
|
if (g_old->graph.graphColour2 != g_new->graph.graphColour2)
|
||
|
XSetForeground(XtDisplay(new),
|
||
|
g_new->graph.graphGC2,
|
||
|
g_new->graph.graphColour2);
|
||
|
|
||
|
if (g_old->graph.graphColour3 != g_new->graph.graphColour3)
|
||
|
XSetForeground(XtDisplay(new),
|
||
|
g_new->graph.graphGC3,
|
||
|
g_new->graph.graphColour3);
|
||
|
|
||
|
if (g_old->graph.graphColour4 != g_new->graph.graphColour4)
|
||
|
XSetForeground(XtDisplay(new),
|
||
|
g_new->graph.graphGC4,
|
||
|
g_new->graph.graphColour4);
|
||
|
|
||
|
return(True);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ---- Exported procedures ---- */
|
||
|
|
||
|
|
||
|
GC GraphGC1(Widget w)
|
||
|
{ return((GraphWidget)w)->graph.graphGC1;
|
||
|
}
|
||
|
|
||
|
|
||
|
GC GraphGC2(Widget w)
|
||
|
{ return((GraphWidget)w)->graph.graphGC2;
|
||
|
}
|
||
|
|
||
|
|
||
|
GC GraphGC3(Widget w)
|
||
|
{ return((GraphWidget)w)->graph.graphGC3;
|
||
|
}
|
||
|
|
||
|
|
||
|
GC GraphGC4(Widget w)
|
||
|
{ return((GraphWidget)w)->graph.graphGC4;
|
||
|
}
|