xgX.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
- /*
- * Generic Output Driver for X
- * X version 11
- *
- * This is the primary output driver used by the new X graph
- * to display output to the X server. It has been factored
- * out of the original xgraph to allow mulitple hardcopy
- * output devices to share xgraph's capabilities. Note:
- * xgraph is still heavily X oriented. This is not intended
- * for porting to other window systems.
- */
- #include "copyright.h"
- #include "xgout.h"
- #include "params.h"
- #define PADDING 2
- #define SPACE 10
- #define TICKLENGTH 5
- #define MAXSEGS 1000
- struct x_state {
- Window win; /* Primary window */
- };
- void text_X();
- void seg_X();
- void dot_X();
- typedef struct attr_set {
- char lineStyle[MAXLS];
- int lineStyleLen;
- Pixel pixelValue;
- Pixmap markStyle;
- } AttrSet;
- static AttrSet AllAttrs[MAXATTR];
- static Pixmap dotMap = (Pixmap) 0;
- /*
- * Marker bitmaps
- */
- #include "bitmaps/dot.11"
- #include "bitmaps/mark1.11"
- #include "bitmaps/mark2.11"
- #include "bitmaps/mark3.11"
- #include "bitmaps/mark4.11"
- #include "bitmaps/mark5.11"
- #include "bitmaps/mark6.11"
- #include "bitmaps/mark7.11"
- #include "bitmaps/mark8.11"
- /* Sizes exported for marker drawing */
- static unsigned int dot_w = dot_width;
- static unsigned int dot_h = dot_height;
- static unsigned int mark_w = mark1_width;
- static unsigned int mark_h = mark1_height;
- static int mark_cx = mark1_x_hot;
- static int mark_cy = mark1_y_hot;
- void
- set_X(new_win, out_info)
- Window new_win; /* Newly created window */
- xgOut *out_info; /* Information to set */
- /*
- * Sets some of the common parameters for the X output device.
- */
- {
- struct x_state *new_state;
- XFontStruct *font;
- out_info->dev_flags = ((depth > 3) ? D_COLOR : 0);
- out_info->area_w = out_info->area_h = 0; /* Set later */
- out_info->bdr_pad = PADDING;
- out_info->axis_pad = SPACE;
- out_info->legend_pad = 0;
- out_info->tick_len = TICKLENGTH;
- font = PM_FONT("LabelFont");
- #ifdef OLD
- out_info->axis_width =
- font->max_bounds.rbearing - font->max_bounds.lbearing;
- #endif
- out_info->axis_width = XTextWidth(font, "8", 1);
- out_info->axis_height =
- font->max_bounds.ascent + font->max_bounds.descent;
- font = PM_FONT("TitleFont");
- #ifdef OLD
- out_info->title_width =
- font->max_bounds.rbearing - font->max_bounds.lbearing;
- #endif
- out_info->title_width = XTextWidth(font, "8", 1);
- out_info->title_height =
- font->max_bounds.ascent + font->max_bounds.descent;
- out_info->max_segs = MAXSEGS;
- out_info->xg_text = text_X;
- out_info->xg_seg = seg_X;
- out_info->xg_dot = dot_X;
- out_info->xg_end = (void (*) ()) 0;
- new_state = (struct x_state *) Malloc(sizeof(struct x_state));
- new_state->win = new_win;
- out_info->user_state = (char *) new_state;
- }
- static void
- init_once()
- /*
- * Initializes AllAttrs.
- */
- {
- Window temp_win;
- XSetWindowAttributes wattr;
- char name[1024];
- int idx;
- params style_val;
- /* Get attributes out parameters database */
- for (idx = 0; idx < MAXATTR; idx++) {
- (void) sprintf(name, "%d.Style", idx);
- (void) param_get(name, &style_val);
- AllAttrs[idx].lineStyleLen = style_val.stylev.len;
- (void) strncpy(AllAttrs[idx].lineStyle, style_val.stylev.dash_list,
- style_val.stylev.len);
- (void) sprintf(name, "%d.Color", idx);
- AllAttrs[idx].pixelValue = PM_PIXEL(name);
- }
- /* Create a temporary window for representing depth */
- temp_win = XCreateWindow(disp, RootWindow(disp, screen),
- 0, 0, 10, 10, 0, depth, InputOutput,
- vis, (unsigned long) 0, &wattr);
- /* Store bitmaps for dots and markers */
- dotMap = XCreateBitmapFromData(disp, temp_win, dot_bits, dot_w, dot_h);
- AllAttrs[0].markStyle = XCreateBitmapFromData(disp, temp_win,
- mark1_bits, mark_w, mark_h);
- AllAttrs[1].markStyle = XCreateBitmapFromData(disp, temp_win,
- mark2_bits, mark_w, mark_h);
- AllAttrs[2].markStyle = XCreateBitmapFromData(disp, temp_win,
- mark3_bits, mark_w, mark_h);
- AllAttrs[3].markStyle = XCreateBitmapFromData(disp, temp_win,
- mark4_bits, mark_w, mark_h);
- AllAttrs[4].markStyle = XCreateBitmapFromData(disp, temp_win,
- mark5_bits, mark_w, mark_h);
- AllAttrs[5].markStyle = XCreateBitmapFromData(disp, temp_win,
- mark6_bits, mark_w, mark_h);
- AllAttrs[6].markStyle = XCreateBitmapFromData(disp, temp_win,
- mark7_bits, mark_w, mark_h);
- AllAttrs[7].markStyle = XCreateBitmapFromData(disp, temp_win,
- mark8_bits, mark_w, mark_h);
- XDestroyWindow(disp, temp_win);
- }
- /*ARGSUSED*/
- void
- init_X(user_state)
- char *user_state;
- /*
- * Initializes for an X drawing sequence. Sets up drawing attributes
- * by reading values from the parameter database.
- */
- {
- static int initialized = 0;
- if (!initialized) {
- init_once();
- initialized = 1;
- }
- }
- static GC
- textGC(t_win, t_font)
- Window t_win; /* Window for making GC */
- XFontStruct *t_font; /* Text font */
- /*
- * Sets the fields above in a global graphics context. If
- * the graphics context does not exist, it is created.
- */
- {
- static GC text_gc = (GC) 0;
- XGCValues gcvals;
- unsigned long gcmask;
- gcvals.font = t_font->fid;
- gcmask = GCFont;
- if (text_gc == (GC) 0) {
- gcvals.foreground = PM_PIXEL("Foreground");
- gcmask |= GCForeground;
- text_gc = XCreateGC(disp, t_win, gcmask, &gcvals);
- }
- else {
- XChangeGC(disp, text_gc, gcmask, &gcvals);
- }
- return text_gc;
- }
- static GC
- segGC(l_win, l_fg, l_style, l_width, l_chars, l_len)
- Window l_win; /* Window for making GC */
- Pixel l_fg; /* Foreground color */
- int l_style; /* Line style */
- int l_width; /* Line width */
- char *l_chars; /* Character spec */
- int l_len; /* Length of spec */
- /*
- * Sets the fields above in a global graphics context. If the
- * graphics context does not exist, it is created.
- */
- {
- static GC segment_gc = (GC) 0;
- XGCValues gcvals;
- unsigned long gcmask;
- gcvals.foreground = l_fg;
- gcvals.line_style = l_style;
- gcvals.line_width = l_width;
- gcmask = GCForeground | GCLineStyle | GCLineWidth;
- if (segment_gc == (GC) 0) {
- segment_gc = XCreateGC(disp, l_win, gcmask, &gcvals);
- }
- else {
- XChangeGC(disp, segment_gc, gcmask, &gcvals);
- }
- if (l_len > 0) {
- XSetDashes(disp, segment_gc, 0, l_chars, l_len);
- }
- return segment_gc;
- }
- static GC
- dotGC(d_win, d_fg, d_clipmask, d_xorg, d_yorg)
- Window d_win; /* Window for making GC */
- Pixel d_fg; /* Foreground color */
- Pixmap d_clipmask; /* Clipmask */
- int d_xorg,
- d_yorg; /* Clipmask origin */
- /*
- * Sets the fields above in a global graphics context. If the
- * graphics context does not exist, it is created.
- */
- {
- static GC dot_gc = (GC) 0;
- XGCValues gcvals;
- unsigned long gcmask;
- gcvals.foreground = d_fg;
- gcvals.clip_mask = d_clipmask;
- gcvals.clip_x_origin = d_xorg;
- gcvals.clip_y_origin = d_yorg;
- gcmask = GCForeground | GCClipMask | GCClipXOrigin | GCClipYOrigin;
- if (dot_gc == (GC) 0) {
- dot_gc = XCreateGC(disp, d_win, gcmask, &gcvals);
- }
- else {
- XChangeGC(disp, dot_gc, gcmask, &gcvals);
- }
- return dot_gc;
- }
- void
- text_X(user_state, x, y, text, just, style)
- char *user_state; /* Value set in xg_init */
- int x,
- y; /* Text position (pixels) */
- char *text; /* Null terminated text */
- int just; /* Justification (above) */
- int style; /* Text style (above) */
- /*
- * This routine should draw text at the indicated position using
- * the indicated justification and style. The justification refers
- * to the location of the point in reference to the text. For example,
- * if just is T_LOWERLEFT, (x,y) should be located at the lower left
- * edge of the text string.
- */
- {
- struct x_state *st = (struct x_state *) user_state;
- XCharStruct bb;
- int rx = 0,
- ry = 0,
- len,
- height,
- width,
- dir;
- int ascent,
- descent;
- XFontStruct *font;
- len = strlen(text);
- font = ((style == T_TITLE) ? PM_FONT("TitleFont") : PM_FONT("LabelFont"));
- XTextExtents(font, text, len, &dir, &ascent, &descent, &bb);
- width = bb.rbearing - bb.lbearing;
- height = bb.ascent + bb.descent;
- switch (just) {
- case T_CENTER:
- rx = x - (width / 2);
- ry = y - (height / 2);
- break;
- case T_LEFT:
- rx = x;
- ry = y - (height / 2);
- break;
- case T_UPPERLEFT:
- rx = x;
- ry = y;
- break;
- case T_TOP:
- rx = x - (width / 2);
- ry = y;
- break;
- case T_UPPERRIGHT:
- rx = x - width;
- ry = y;
- break;
- case T_RIGHT:
- rx = x - width;
- ry = y - (height / 2);
- break;
- case T_LOWERRIGHT:
- rx = x - width;
- ry = y - height;
- break;
- case T_BOTTOM:
- rx = x - (width / 2);
- ry = y - height;
- break;
- case T_LOWERLEFT:
- rx = x;
- ry = y - height;
- break;
- }
- XDrawString(disp, st->win,
- textGC(st->win, font),
- rx, ry + bb.ascent, text, len);
- }
- void
- seg_X(user_state, ns, segs, width, style, lappr, color)
- char *user_state; /* Value set in xg_init */
- int ns; /* Number of segments */
- XSegment *segs; /* X array of segments */
- int width; /* Width of lines */
- int style; /* See above */
- int lappr; /* Line appearence */
- int color; /* Line color (if any) */
- /*
- * This routine draws a number of line segments at the points
- * given in `seglist'. Note that contiguous segments need not share
- * endpoints but often do. All segments should be `width' devcoords wide
- * and drawn in style `style'. If `style' is L_VAR, the parameters
- * `color' and `lappr' should be used to draw the line. Both
- * parameters vary from 0 to 7. If the device is capable of
- * color, `color' varies faster than `style'. If the device
- * has no color, `style' will vary faster than `color' and
- * `color' can be safely ignored. However, if the
- * the device has more than 8 line appearences, the two can
- * be combined to specify 64 line style variations.
- * Xgraph promises not to send more than the `max_segs' in the
- * xgOut structure passed back from xg_init().
- */
- {
- struct x_state *st = (struct x_state *) user_state;
- param_style ps;
- GC gc;
- if (style == L_AXIS) {
- ps = PM_STYLE("GridStyle");
- if (ps.len < 2) {
- gc = segGC(st->win, PM_PIXEL("Foreground"),
- LineSolid, PM_INT("GridSize"), (char *) 0, 0);
- }
- else {
- gc = segGC(st->win, PM_PIXEL("Foreground"),
- LineOnOffDash, PM_INT("GridSize"),
- ps.dash_list, ps.len);
- }
- }
- else if (style == L_ZERO) {
- /* Set the color and line style */
- ps = PM_STYLE("ZeroStyle");
- if (ps.len < 2) {
- gc = segGC(st->win, PM_PIXEL("ZeroColor"),
- LineSolid, PM_INT("ZeroWidth"), (char *) 0, 0);
- }
- else {
- gc = segGC(st->win, PM_PIXEL("ZeroColor"),
- LineOnOffDash, PM_INT("ZeroWidth"),
- ps.dash_list, ps.len);
- }
- }
- else {
- /* Color and line style vary */
- if (lappr == 0) {
- gc = segGC(st->win, AllAttrs[color].pixelValue, LineSolid,
- width, (char *) 0, 0);
- }
- else {
- gc = segGC(st->win, AllAttrs[color].pixelValue, LineOnOffDash,
- width, AllAttrs[lappr].lineStyle, AllAttrs[lappr].lineStyleLen);
- }
- /* PW */
- if (lappr == 16) {
- gc = segGC(st->win, PM_PIXEL("BackGround"), LineSolid,
- width, (char *) 0, 0);
- }
- }
- XDrawSegments(disp, st->win, gc, segs, ns);
- }
- #define LAST_CHECK
- void
- dot_X(user_state, x, y, style, type, color)
- char *user_state; /* Value set in xg_init */
- int x,
- y; /* Location in pixel units */
- int style; /* Dot style */
- int type; /* Type of marker */
- int color; /* Marker color (if any) */
- /*
- * This routine should draw a marker at location `x,y'. If the
- * style is P_PIXEL, the dot should be a single pixel. If
- * the style is P_DOT, the dot should be a reasonably large
- * dot. If the style is P_MARK, it should be a distinguished
- * mark which is specified by `type' (0-7). If the output
- * device is capable of color, the marker should be drawn in
- * `color' (0-7) which corresponds with the color for xg_line.
- */
- {
- struct x_state *st = (struct x_state *) user_state;
- switch (style) {
- case P_PIXEL:
- XDrawPoint(disp, st->win,
- dotGC(st->win, AllAttrs[color].pixelValue, (Pixmap) 0, 0, 0),
- x, y);
- break;
- case P_DOT:
- XFillRectangle(disp, st->win,
- dotGC(st->win, AllAttrs[color].pixelValue, dotMap,
- (int) (x - (dot_w >> 1)),
- (int) (y - (dot_h >> 1))),
- (int) (x - (dot_w >> 1)), (int) (y - (dot_h >> 1)),
- dot_w, dot_h);
- break;
- case P_MARK:
- XFillRectangle(disp, st->win,
- dotGC(st->win, AllAttrs[color].pixelValue,
- AllAttrs[type].markStyle,
- (int) (x - mark_cx),
- (int) (y - mark_cy)),
- (int) (x - mark_cx), (int) (y - mark_cy),
- mark_w, mark_h);
- break;
- }
- }