The edm display manager currently depend on X Windows, and while it is not necessary to have expert knowledge, some experience with the X Windows programming model is required in order to build a new edm widget. Of course, it is possible to make extensive use of X, including using an X Toolkit (like motif), thus clearly the more X Windows knowledge, the more sophisticated the edm widget. This document targets the less experienced X Windows developer and will not address issues involved with using motif. The objective is to enable the widget devoloper to be able to draw simple geometrical shapes and display text.
To draw lines, rectangles, and ellipses, you need the following:
A display object - this is obtained as actWin->d
A window on which to draw - this is obtained as XtWindow(actWin->drawWidget) or XtWindow(actWin->executeWidget) for edit and execute mode respectively.
A graphics context object - this is obtained as actWin->drawGc or actWin->executeGc for edit and execute mode respectively.
For points and lines you need to use an XPoint/ or XSegment structure.
typedef struct {
short x1, y1, x2, y2;
} XSegment;
typedef struct {
short x, y;
} XPoint;For text you need to use and XFontStruct object and several edm font related objects that hide some of the gory details.
To use colors, you need to use several edm color related objects.
Finally you need several Xlib function definitions, and the names of a few useful Xlib constants.
Refer to the Xlib Programming Manual for the definition of various useful constants. See Chaper 5, The Graphics Context and Chapter 6, Drawing Graphics and Text.
Function definitions and the definition of some constants may be found in the Xlib Reference manual. In particular, examine documentation for the following functions:
XDrawArc
XDrawImageString
XDrawLines
XDrawRectangle
XDrawSegments
XDrawString
XFillArc
XFillPolygon
XFillRectangle
The following gives examples of drawing shapes and displaying text. At this point, don't be concerned with how colors and fonts are obtained. These are topics to be discussed in more detail later. Also, note that the origin of an X display is at the upper left of the screen.
// edit mode
// save current foreground color
actWin->drawGc.saveFg();
// set graphics context to user selected color, linestyle, and width
actWin->drawGc.setLineStyle( lineStyle );
actWin->drawGc.setLineWidth( lineWidth );
actWin->drawGc.setFG( lineColor.pixelColor(), &blink );
// draw outline objects
// rectangle
XDrawRectangle( actWin->d, XtWindow(actWin->drawWidget),
actWin->drawGc.normGC(), x, y, w, h );
// ellipse - 0, 23040 are starting angle, angle length in 1/64 degrees
XDrawArc( actWin->d, XtWindow(actWin->drawWidget), actWin->drawGc.normGC(),
x, y, w, h, 0, 23040 );
// lines
XPoint xpoints[3];
xpoints[0].x = 0;
xpoints[0].y = 0;
xpoints[1].x = 5;
xpoints[1].y = 10;
xpoints[2].x = 1;
xpoints[2].y = 1;
n = 3;
XDrawLines( actWin->d, XtWindow(actWin->drawWidget),
actWin->drawGc.normGC(), xpoints, n, CoordModeOrigin );
// draw filled objects
// rectangle
XFillRectangle( actWin->d, XtWindow(actWin->drawWidget),
actWin->drawGc.normGC(), x, y, w, h );
// ellipse - 0, 23040 are starting angle, angle length in 1/64 degrees
XFillArc( actWin->d, XtWindow(actWin->drawWidget), actWin->drawGc.normGC(),
x, y, w, h, 0, 23040 );
// lines
XPoint xpoints[3];
xpoints[0].x = 0;
xpoints[0].y = 0;
xpoints[1].x = 5;
xpoints[1].y = 10;
xpoints[2].x = 1;
xpoints[2].y = 1;
n = 3;
XFillPolygon( actWin->d, XtWindow(actWin->drawWidget),
actWin->drawGc.normGC(), xpoints, n, Complex, CoordModeOrigin );
// this is necessary if blinking colors are to be supported
updateBlink( blink );
// restore grapics context info
actWin->drawGc.setLineWidth( 1 );
actWin->drawGc.setLineStyle( LineSolid );
actWin->drawGc.restoreFg();
// a few other capabilities of the edm graphics context
// draw rectangle in exclusive or mode
XDrawRectangle( actWin->d, XtWindow(actWin->drawWidget),
actWin->drawGc.xorGC(), x, y, w, h );
// erase rectangle using edm display background color
XDrawRectangle( actWin->d, XtWindow(actWin->drawWidget),
actWin->drawGc.eraseGC(), x, y, w, h );
// Display text
// make font available to X Server and specify to graphic context
actWin->fi->loadFontTag( fontTag );
actWin->drawGc.setFontTag( axto->fontTag, axto->actWin->fi );
// set text color
actWin->drawGc.setFG( fgColor.pixelColor(), &blink );
// get X font struct
fs = actWin->fi->getXFontStruct( axto->fontTag );
// get font metrics
updateFont( "text to display", fontTag, &fs,
&fontAscent, &fontDescent, &fontHeight,
&stringWidth );
// you might use font metric in determining exactly where
// to position text (left, center, right aligned, etc.)
// optionally, set up a clipping region
XRectangle xR = { x, y, w, h };
clipStat = actWin->drawGc.addNormXClipRectangle( xR );
// display text
stringLength = strlen( "text to display" );
XDrawString( actWin->d, XtWindow(actWin->drawWidget),
actWin->drawGc.normGC(), stringX, stringY,
"text to display", stringLength );
// remove clipping region
if ( clipStat & 1 ) actWin->drawGc.removeNormXClipRectangle();
// this is necessary if blinking colors are to be supported
updateBlink( blink );