xgX.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Generic Output Driver for X
  3.  * X version 11
  4.  *
  5.  * This is the primary output driver used by the new X graph
  6.  * to display output to the X server.  It has been factored
  7.  * out of the original xgraph to allow mulitple hardcopy
  8.  * output devices to share xgraph's capabilities.  Note:
  9.  * xgraph is still heavily X oriented.  This is not intended
  10.  * for porting to other window systems.
  11.  */
  12. #include "copyright.h"
  13. #include "xgout.h"
  14. #include "params.h"
  15. #define PADDING  2
  16. #define SPACE  10
  17. #define TICKLENGTH 5
  18. #define MAXSEGS 1000
  19. struct x_state {
  20.     Window  win; /* Primary window           */
  21. };
  22. void    text_X();
  23. void    seg_X();
  24. void    dot_X();
  25. typedef struct attr_set {
  26.     char    lineStyle[MAXLS];
  27.     int     lineStyleLen;
  28.     Pixel   pixelValue;
  29.     Pixmap  markStyle;
  30. }       AttrSet;
  31. static AttrSet AllAttrs[MAXATTR];
  32. static Pixmap dotMap = (Pixmap) 0;
  33. /*
  34.  * Marker bitmaps
  35.  */
  36. #include "bitmaps/dot.11"
  37. #include "bitmaps/mark1.11"
  38. #include "bitmaps/mark2.11"
  39. #include "bitmaps/mark3.11"
  40. #include "bitmaps/mark4.11"
  41. #include "bitmaps/mark5.11"
  42. #include "bitmaps/mark6.11"
  43. #include "bitmaps/mark7.11"
  44. #include "bitmaps/mark8.11"
  45. /* Sizes exported for marker drawing */
  46. static unsigned int dot_w = dot_width;
  47. static unsigned int dot_h = dot_height;
  48. static unsigned int mark_w = mark1_width;
  49. static unsigned int mark_h = mark1_height;
  50. static int mark_cx = mark1_x_hot;
  51. static int mark_cy = mark1_y_hot;
  52. void 
  53. set_X(new_win, out_info)
  54. Window  new_win; /* Newly created window */
  55. xgOut  *out_info; /* Information to set   */
  56. /*
  57.  * Sets some of the common parameters for the X output device.
  58.  */
  59. {
  60.     struct x_state *new_state;
  61.     XFontStruct *font;
  62.     out_info->dev_flags = ((depth > 3) ? D_COLOR : 0);
  63.     out_info->area_w = out_info->area_h = 0; /* Set later */
  64.     out_info->bdr_pad = PADDING;
  65.     out_info->axis_pad = SPACE;
  66.     out_info->legend_pad = 0;
  67.     out_info->tick_len = TICKLENGTH;
  68.     font = PM_FONT("LabelFont");
  69. #ifdef OLD
  70.     out_info->axis_width =
  71. font->max_bounds.rbearing - font->max_bounds.lbearing;
  72. #endif
  73.     out_info->axis_width = XTextWidth(font, "8", 1);
  74.     out_info->axis_height =
  75. font->max_bounds.ascent + font->max_bounds.descent;
  76.     font = PM_FONT("TitleFont");
  77. #ifdef OLD
  78.     out_info->title_width =
  79. font->max_bounds.rbearing - font->max_bounds.lbearing;
  80. #endif
  81.     out_info->title_width = XTextWidth(font, "8", 1);
  82.     out_info->title_height =
  83. font->max_bounds.ascent + font->max_bounds.descent;
  84.     out_info->max_segs = MAXSEGS;
  85.     out_info->xg_text = text_X;
  86.     out_info->xg_seg = seg_X;
  87.     out_info->xg_dot = dot_X;
  88.     out_info->xg_end = (void (*) ()) 0;
  89.     new_state = (struct x_state *) Malloc(sizeof(struct x_state));
  90.     new_state->win = new_win;
  91.     out_info->user_state = (char *) new_state;
  92. }
  93. static void 
  94. init_once()
  95. /*
  96.  * Initializes AllAttrs.
  97.  */
  98. {
  99.     Window  temp_win;
  100.     XSetWindowAttributes wattr;
  101.     char    name[1024];
  102.     int     idx;
  103.     params  style_val;
  104.     /* Get attributes out parameters database */
  105.     for (idx = 0; idx < MAXATTR; idx++) {
  106. (void) sprintf(name, "%d.Style", idx);
  107. (void) param_get(name, &style_val);
  108. AllAttrs[idx].lineStyleLen = style_val.stylev.len;
  109. (void) strncpy(AllAttrs[idx].lineStyle, style_val.stylev.dash_list,
  110.        style_val.stylev.len);
  111. (void) sprintf(name, "%d.Color", idx);
  112. AllAttrs[idx].pixelValue = PM_PIXEL(name);
  113.     }
  114.     /* Create a temporary window for representing depth */
  115.     temp_win = XCreateWindow(disp, RootWindow(disp, screen),
  116.      0, 0, 10, 10, 0, depth, InputOutput,
  117.      vis, (unsigned long) 0, &wattr);
  118.     /* Store bitmaps for dots and markers */
  119.     dotMap = XCreateBitmapFromData(disp, temp_win, dot_bits, dot_w, dot_h);
  120.     AllAttrs[0].markStyle = XCreateBitmapFromData(disp, temp_win,
  121.   mark1_bits, mark_w, mark_h);
  122.     AllAttrs[1].markStyle = XCreateBitmapFromData(disp, temp_win,
  123.   mark2_bits, mark_w, mark_h);
  124.     AllAttrs[2].markStyle = XCreateBitmapFromData(disp, temp_win,
  125.   mark3_bits, mark_w, mark_h);
  126.     AllAttrs[3].markStyle = XCreateBitmapFromData(disp, temp_win,
  127.   mark4_bits, mark_w, mark_h);
  128.     AllAttrs[4].markStyle = XCreateBitmapFromData(disp, temp_win,
  129.   mark5_bits, mark_w, mark_h);
  130.     AllAttrs[5].markStyle = XCreateBitmapFromData(disp, temp_win,
  131.   mark6_bits, mark_w, mark_h);
  132.     AllAttrs[6].markStyle = XCreateBitmapFromData(disp, temp_win,
  133.   mark7_bits, mark_w, mark_h);
  134.     AllAttrs[7].markStyle = XCreateBitmapFromData(disp, temp_win,
  135.   mark8_bits, mark_w, mark_h);
  136.     XDestroyWindow(disp, temp_win);
  137. }
  138. /*ARGSUSED*/
  139. void 
  140. init_X(user_state)
  141. char   *user_state;
  142. /*
  143.  * Initializes for an X drawing sequence.  Sets up drawing attributes
  144.  * by reading values from the parameter database.
  145.  */
  146. {
  147.     static int initialized = 0;
  148.     if (!initialized) {
  149. init_once();
  150. initialized = 1;
  151.     }
  152. }
  153. static GC 
  154. textGC(t_win, t_font)
  155. Window  t_win; /* Window for making GC */
  156. XFontStruct *t_font; /* Text font            */
  157. /*
  158.  * Sets the fields above in a global graphics context.  If
  159.  * the graphics context does not exist,  it is created.
  160.  */
  161. {
  162.     static GC text_gc = (GC) 0;
  163.     XGCValues gcvals;
  164.     unsigned long gcmask;
  165.     gcvals.font = t_font->fid;
  166.     gcmask = GCFont;
  167.     if (text_gc == (GC) 0) {
  168. gcvals.foreground = PM_PIXEL("Foreground");
  169. gcmask |= GCForeground;
  170. text_gc = XCreateGC(disp, t_win, gcmask, &gcvals);
  171.     }
  172.     else {
  173. XChangeGC(disp, text_gc, gcmask, &gcvals);
  174.     }
  175.     return text_gc;
  176. }
  177. static GC 
  178. segGC(l_win, l_fg, l_style, l_width, l_chars, l_len)
  179. Window  l_win; /* Window for making GC */
  180. Pixel   l_fg; /* Foreground color */
  181. int     l_style; /* Line style       */
  182. int     l_width; /* Line width       */
  183. char   *l_chars; /* Character spec   */
  184. int     l_len; /* Length of spec   */
  185. /*
  186.  * Sets the fields above in a global graphics context.  If the
  187.  * graphics context does not exist, it is created.
  188.  */
  189. {
  190.     static GC segment_gc = (GC) 0;
  191.     XGCValues gcvals;
  192.     unsigned long gcmask;
  193.     gcvals.foreground = l_fg;
  194.     gcvals.line_style = l_style;
  195.     gcvals.line_width = l_width;
  196.     gcmask = GCForeground | GCLineStyle | GCLineWidth;
  197.     if (segment_gc == (GC) 0) {
  198. segment_gc = XCreateGC(disp, l_win, gcmask, &gcvals);
  199.     }
  200.     else {
  201. XChangeGC(disp, segment_gc, gcmask, &gcvals);
  202.     }
  203.     if (l_len > 0) {
  204. XSetDashes(disp, segment_gc, 0, l_chars, l_len);
  205.     }
  206.     return segment_gc;
  207. }
  208. static GC 
  209. dotGC(d_win, d_fg, d_clipmask, d_xorg, d_yorg)
  210. Window  d_win; /* Window for making GC */
  211. Pixel   d_fg; /* Foreground color */
  212. Pixmap  d_clipmask; /* Clipmask         */
  213. int     d_xorg,
  214.         d_yorg; /* Clipmask origin  */
  215. /*
  216.  * Sets the fields above in a global graphics context.  If the
  217.  * graphics context does not exist, it is created.
  218.  */
  219. {
  220.     static GC dot_gc = (GC) 0;
  221.     XGCValues gcvals;
  222.     unsigned long gcmask;
  223.     gcvals.foreground = d_fg;
  224.     gcvals.clip_mask = d_clipmask;
  225.     gcvals.clip_x_origin = d_xorg;
  226.     gcvals.clip_y_origin = d_yorg;
  227.     gcmask = GCForeground | GCClipMask | GCClipXOrigin | GCClipYOrigin;
  228.     if (dot_gc == (GC) 0) {
  229. dot_gc = XCreateGC(disp, d_win, gcmask, &gcvals);
  230.     }
  231.     else {
  232. XChangeGC(disp, dot_gc, gcmask, &gcvals);
  233.     }
  234.     return dot_gc;
  235. }
  236. void 
  237. text_X(user_state, x, y, text, just, style)
  238. char   *user_state; /* Value set in xg_init   */
  239. int     x,
  240.         y; /* Text position (pixels) */
  241. char   *text; /* Null terminated text   */
  242. int     just; /* Justification (above)  */
  243. int     style; /* Text style (above)     */
  244. /*
  245.  * This routine should draw text at the indicated position using
  246.  * the indicated justification and style.  The justification refers
  247.  * to the location of the point in reference to the text.  For example,
  248.  * if just is T_LOWERLEFT,  (x,y) should be located at the lower left
  249.  * edge of the text string.
  250.  */
  251. {
  252.     struct x_state *st = (struct x_state *) user_state;
  253.     XCharStruct bb;
  254.     int     rx = 0,
  255.             ry = 0,
  256.             len,
  257.             height,
  258.             width,
  259.             dir;
  260.     int     ascent,
  261.             descent;
  262.     XFontStruct *font;
  263.     len = strlen(text);
  264.     font = ((style == T_TITLE) ? PM_FONT("TitleFont") : PM_FONT("LabelFont"));
  265.     XTextExtents(font, text, len, &dir, &ascent, &descent, &bb);
  266.     width = bb.rbearing - bb.lbearing;
  267.     height = bb.ascent + bb.descent;
  268.     switch (just) {
  269.     case T_CENTER:
  270. rx = x - (width / 2);
  271. ry = y - (height / 2);
  272. break;
  273.     case T_LEFT:
  274. rx = x;
  275. ry = y - (height / 2);
  276. break;
  277.     case T_UPPERLEFT:
  278. rx = x;
  279. ry = y;
  280. break;
  281.     case T_TOP:
  282. rx = x - (width / 2);
  283. ry = y;
  284. break;
  285.     case T_UPPERRIGHT:
  286. rx = x - width;
  287. ry = y;
  288. break;
  289.     case T_RIGHT:
  290. rx = x - width;
  291. ry = y - (height / 2);
  292. break;
  293.     case T_LOWERRIGHT:
  294. rx = x - width;
  295. ry = y - height;
  296. break;
  297.     case T_BOTTOM:
  298. rx = x - (width / 2);
  299. ry = y - height;
  300. break;
  301.     case T_LOWERLEFT:
  302. rx = x;
  303. ry = y - height;
  304. break;
  305.     }
  306.     XDrawString(disp, st->win,
  307. textGC(st->win, font),
  308. rx, ry + bb.ascent, text, len);
  309. }
  310. void 
  311. seg_X(user_state, ns, segs, width, style, lappr, color)
  312. char   *user_state; /* Value set in xg_init */
  313. int     ns; /* Number of segments   */
  314. XSegment *segs; /* X array of segments  */
  315. int     width; /* Width of lines       */
  316. int     style; /* See above            */
  317. int     lappr; /* Line appearence      */
  318. int     color; /* Line color (if any)  */
  319. /*
  320.  * This routine draws a number of line segments at the points
  321.  * given in `seglist'.  Note that contiguous segments need not share
  322.  * endpoints but often do.  All segments should be `width' devcoords wide
  323.  * and drawn in style `style'.  If `style' is L_VAR,  the parameters
  324.  * `color' and `lappr' should be used to draw the line.  Both
  325.  * parameters vary from 0 to 7.  If the device is capable of
  326.  * color,  `color' varies faster than `style'.  If the device
  327.  * has no color,  `style' will vary faster than `color' and
  328.  * `color' can be safely ignored.  However,  if the
  329.  * the device has more than 8 line appearences,  the two can
  330.  * be combined to specify 64 line style variations.
  331.  * Xgraph promises not to send more than the `max_segs' in the
  332.  * xgOut structure passed back from xg_init().
  333.  */
  334. {
  335.     struct x_state *st = (struct x_state *) user_state;
  336.     param_style ps;
  337.     GC      gc;
  338.     if (style == L_AXIS) {
  339. ps = PM_STYLE("GridStyle");
  340. if (ps.len < 2) {
  341.     gc = segGC(st->win, PM_PIXEL("Foreground"),
  342.        LineSolid, PM_INT("GridSize"), (char *) 0, 0);
  343. }
  344. else {
  345.     gc = segGC(st->win, PM_PIXEL("Foreground"),
  346.        LineOnOffDash, PM_INT("GridSize"),
  347.        ps.dash_list, ps.len);
  348. }
  349.     }
  350.     else if (style == L_ZERO) {
  351. /* Set the color and line style */
  352. ps = PM_STYLE("ZeroStyle");
  353. if (ps.len < 2) {
  354.     gc = segGC(st->win, PM_PIXEL("ZeroColor"),
  355.        LineSolid, PM_INT("ZeroWidth"), (char *) 0, 0);
  356. }
  357. else {
  358.     gc = segGC(st->win, PM_PIXEL("ZeroColor"),
  359.        LineOnOffDash, PM_INT("ZeroWidth"),
  360.        ps.dash_list, ps.len);
  361. }
  362.     }
  363.     else {
  364. /* Color and line style vary */
  365. if (lappr == 0) {
  366.     gc = segGC(st->win, AllAttrs[color].pixelValue, LineSolid,
  367.        width, (char *) 0, 0);
  368. }
  369. else {
  370.     gc = segGC(st->win, AllAttrs[color].pixelValue, LineOnOffDash,
  371.       width, AllAttrs[lappr].lineStyle, AllAttrs[lappr].lineStyleLen);
  372. }
  373.         /* PW */
  374. if (lappr == 16) {
  375.     gc = segGC(st->win, PM_PIXEL("BackGround"), LineSolid,
  376.        width, (char *) 0, 0);
  377. }
  378.     }
  379.     XDrawSegments(disp, st->win, gc, segs, ns);
  380. }
  381. #define LAST_CHECK
  382. void 
  383. dot_X(user_state, x, y, style, type, color)
  384. char   *user_state; /* Value set in xg_init    */
  385. int     x,
  386.         y; /* Location in pixel units */
  387. int     style; /* Dot style               */
  388. int     type; /* Type of marker          */
  389. int     color; /* Marker color (if any)   */
  390. /*
  391.  * This routine should draw a marker at location `x,y'.  If the
  392.  * style is P_PIXEL,  the dot should be a single pixel.  If
  393.  * the style is P_DOT,  the dot should be a reasonably large
  394.  * dot.  If the style is P_MARK,  it should be a distinguished
  395.  * mark which is specified by `type' (0-7).  If the output
  396.  * device is capable of color,  the marker should be drawn in
  397.  * `color' (0-7) which corresponds with the color for xg_line.
  398.  */
  399. {
  400.     struct x_state *st = (struct x_state *) user_state;
  401.     switch (style) {
  402.     case P_PIXEL:
  403. XDrawPoint(disp, st->win,
  404.  dotGC(st->win, AllAttrs[color].pixelValue, (Pixmap) 0, 0, 0),
  405.    x, y);
  406. break;
  407.     case P_DOT:
  408. XFillRectangle(disp, st->win,
  409.        dotGC(st->win, AllAttrs[color].pixelValue, dotMap,
  410.      (int) (x - (dot_w >> 1)),
  411.      (int) (y - (dot_h >> 1))),
  412.        (int) (x - (dot_w >> 1)), (int) (y - (dot_h >> 1)),
  413.        dot_w, dot_h);
  414. break;
  415.     case P_MARK:
  416. XFillRectangle(disp, st->win,
  417.        dotGC(st->win, AllAttrs[color].pixelValue,
  418.      AllAttrs[type].markStyle,
  419.      (int) (x - mark_cx),
  420.      (int) (y - mark_cy)),
  421.        (int) (x - mark_cx), (int) (y - mark_cy),
  422.        mark_w, mark_h);
  423. break;
  424.     }
  425. }