Fortunately drawing in X is much simpler than creating
windows. The only preparation that we need to do before we can
start drawing is to create a graphics context (GC). This data
structure contains virtually everything needed to specify pen
parameters for drawing. Some examples of what can be defined
include :
- Foreground colour
- Background colour
- Pen width
- Line type (eg. solid, dashed, double dashed)
- Join type (eg. miter, round or bevelled)
The X library maintains a complex cache of GC values, so always treat the structure as read only. Never try to directly write to the structure, always use the GC functions to set the values. With this warning in mind we will show the data structure.
typedef struct _XGC {
XExtData *ext_data;
GContext gid;
Bool rects;
Bool dashes;
unsigned long dirty;
XGCValues values;
} *GC;
To create a graphics context the XCreateGC function is used.
Display *display;
Drawable drawable; /* Eg. window id */
XGCValues xgcvalues;
unsigned long valuemask;
GC gc;
valuemask = 0L; /* No options filled in */
gc = XCreateGC (display, drawable, valuemask, &xgcvalues );
|
The changes that we are most likely to want to make are to the foreground and background colours. One method of doing this is given below.
Display *display;
int screen;
GC gc;
unsigned long f_colour;
unsigned long b_colour;
f_colour = BlackPixel(display, screen);
b_colour = WhitePixel(display, screen);
XSetForeground ( display, gc, f_colour );
XSetBackground ( display, gc, b_colour );
The function XDrawLine draws a line between pixel (x1, y1) and pixel (x2, y2).
Display *display;
Drawable drawable;
GC gc;
int x1, y1;
int x2, y2;
XDrawLine ( display, drawable, gc, x1, y1, x2, y2);
Sometimes we will wish to draw more complicated shapes than just lines. X also understands how to draw rectangles and arcs. The functions used are given below.
Display *display;
Drawable drawable;
GC gc;
int x, y;
unsigned int width, height;
XDrawRectangle ( display, drawable, gc, x, y, width, height);
Drawing arcs or circles is a similar exercise. You define the bounding rectangle for the arc, and the start angle and path angle (the angle size swept out by the arc). All angles are measured in 1/64 of a degree, eg. 90 degrees is 90 x 64 = 5760 units. An angle of 0 units is the direction of the positive x- axis, and anticlockwise is positive.
Display *display;
Drawable drawable;
GC gc;
int x, y;
unsigned int width, height;
int start_angle;
int path_angle;
XDrawArc ( display, drawable, gc, x, y, width, height,
start_angle, path_angle);
The routines described above draw hollow shapes. As you have already guessed, there are similar routines for drawing solid shapes. For completeness, we list the filled version of the above routines.
Display *display;
Drawable drawable;
GC gc;
int x, y;
unsigned int width, height;
int start_angle;
int path_angle;
XFillRectangle ( display, drawable, gc, x, y, width, height);
XFillArc ( display, drawable, gc, x, y, width, height,
start_angle, path_angle);
You can also draw multiple objects of a type at a time, rather than sending your requests singularly. This has efficiency advantages, but be careful if you are using an older version of X. There are only so many requests that you can bundle together into one network packet and send off to the X server. Newer versions of X will break up very large requests, but older versions didn't break up big requests into packets.
There our ways to check on the max request size (XMaxRequestSize(display)), but we won't go into that in this course. Just be aware that this could be a potential limitation.
X defines the following structures for your use when
drawing multiple objects.
typedef struct {
short x, y;
} XPoint;
typedef struct {
short x, y;
unsigned short width, height;
} XRectangle;
typedef struct {
short x, y;
unsigned short width, height;
short angle1, angle2;
} XArc;
Display display;
Drawable drawable;
GC gc;
XPoint points [ ARBITRARY_SIZE ];
int no_points;
XRectangle rects [ ARBITRARY_SIZE ];
int no_rects;
XArc arcs [ ARBITRARY_SIZE ];
int no_arcs;
int mode;
XDrawPoints (display, drawable, gc, points, no_points, mode);
XDrawLines (display, drawable, gc, points, no_points, mode );
XDrawRectangles (display, drawable, gc, rects, no_rects) ;
XFillRectangles (display, drawable, gc, rects, no_rects );
XDrawArcs ( display, drawable, gc, arcs, no_arcs );
XFillArcs ( display, drawable, gc, arcs, no_arcs );