home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lifeos2.zip / LIFE-1.02 / SOURCE / XDISPLAY.C < prev    next >
C/C++ Source or Header  |  1996-06-04  |  19KB  |  818 lines

  1. /* Copyright 1991 Digital Equipment Corporation.
  2.  ** All Rights Reserved.
  3.  ** Last modified on Thu Feb 17 16:32:31 MET 1994 by rmeyer
  4.  *****************************************************************/
  5. /*     $Id: xdisplaylist.c,v 1.2 1994/12/08 23:37:00 duchier Exp $     */
  6.  
  7. #ifndef lint
  8. static char vcid[] = "$Id: xdisplaylist.c,v 1.2 1994/12/08 23:37:00 duchier Exp $";
  9. #endif /* lint */
  10.  
  11. #ifdef X11
  12.  
  13. #include <stdio.h>
  14. /* #include <malloc.h> 11.9 */
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <fcntl.h>
  18. #include <limits.h>
  19.  
  20. #include <X11/Xlib.h>
  21. #include <X11/Xutil.h>
  22.  
  23. #include "extern.h"
  24. #include "xdisplaylist.h"
  25.  
  26.  
  27. /*****************************************/
  28.  
  29. typedef struct wl_Line
  30. {
  31.     Action action;
  32.     ListLinks links;
  33.     int    x0, y0, x1, y1;
  34.     long function;
  35.     long color;
  36.     long linewidth;
  37. } Line;
  38.  
  39.     
  40. typedef struct wl_Rectangle
  41. {
  42.     Action action;
  43.     ListLinks links;
  44.     int    x, y, width, height;
  45.     long function;
  46.     long color;
  47.     long linewidth;
  48. } Rectangle;
  49.  
  50.  
  51. typedef struct wl_Arc
  52. {
  53.     Action action;
  54.     ListLinks links;
  55.     int    x, y, width, height, startangle, arcangle;
  56.     long function;
  57.     long color;
  58.     long linewidth;
  59. } Arc;
  60.  
  61.  
  62. typedef struct wl_String
  63. {
  64.     Action action;
  65.     ListLinks links;
  66.     int    x, y;
  67.     char *str;
  68.     long function;
  69.     long color;
  70.     long font;
  71. } String;
  72.  
  73.     
  74. typedef struct wl_GraphicClosure
  75. {
  76.     Display *display;
  77.     Drawable drawable;
  78.     GC gc;
  79. } GraphicClosure;
  80.  
  81. typedef struct wl_PostScriptClosure
  82. {
  83.     long display;
  84.     Drawable window;
  85.     long f;
  86.     long height;
  87. } PostScriptClosure;
  88.  
  89. typedef struct wl_Polygon
  90. {
  91.     Action action;
  92.     ListLinks links;
  93.     XPoint *points;
  94.     long npoints;
  95.     long function;
  96.     long color;
  97.     long linewidth;
  98. } Polygon;
  99.  
  100. typedef union wl_DisplayElt
  101. {
  102.     Action action;
  103.     Line line;
  104.     Rectangle rectangle;
  105.     Arc arc;
  106.     String str;
  107.     Polygon polygon;
  108. } DisplayElt;
  109.  
  110. typedef DisplayElt *RefDisplayElt;
  111.  
  112.  
  113. /*****************************************/
  114.  
  115.  
  116. static ListLinks  *x_get_links_of_display_list (elt)
  117.  
  118. DisplayElt *elt;
  119.  
  120. {
  121.     return &((Line *) elt)->links;
  122. }
  123.  
  124.  
  125. ListHeader * x_display_list ()
  126.  
  127. {
  128.     ListHeader *display_list;
  129.  
  130.     display_list = (ListHeader *) malloc (sizeof (ListHeader));
  131.     List_SetLinkProc (display_list, x_get_links_of_display_list);
  132.     return display_list;
  133. }
  134.  
  135. /*****************************************/
  136.  
  137. void x_set_gc (display, gc, function, color, linewidth, font)
  138.  
  139. Display *display;
  140. GC gc;
  141. long function;
  142. unsigned long color;
  143. long linewidth;
  144. Font font;
  145.  
  146. {
  147.     XGCValues gcvalues;
  148.     unsigned long valuemask;
  149.  
  150.  
  151.     gcvalues.function = function;
  152.     gcvalues.foreground = color;
  153.     valuemask = GCFunction | GCForeground;
  154.  
  155.     if (linewidth != xDefaultLineWidth)
  156.     {
  157.     gcvalues.line_width = linewidth;
  158.     valuemask |= GCLineWidth;
  159.     }
  160.  
  161.     if (font != xDefaultFont)
  162.     {
  163.     gcvalues.font = font;
  164.     valuemask |= GCFont;
  165.     }
  166.  
  167.     XChangeGC (display, gc, valuemask, &gcvalues);
  168. }
  169.  
  170.  
  171. /*****************************************/
  172.  
  173. #define AllocDisplayElt() malloc (sizeof (DisplayElt))
  174. #define FreeDisplayElt(E) free (E)
  175.  
  176.  
  177. void x_record_line (displaylist, action, x0, y0, x1, y1,
  178.             function, color, linewidth)
  179.  
  180. ListHeader *displaylist;
  181. Action action;
  182. long x0, y0, x1, y1;
  183. unsigned long function, color, linewidth;
  184.  
  185. {
  186.     Line * elt;
  187.  
  188.     elt = (Line *) AllocDisplayElt ();
  189.     elt->action = action;
  190.     elt->x0 = x0;
  191.     elt->y0 = y0;
  192.     elt->x1 = x1;
  193.     elt->y1 = y1;
  194.     elt->function = function;
  195.     elt->color = color;
  196.     elt->linewidth = linewidth;
  197.     List_Append (displaylist, (Ref) elt);
  198. }
  199.  
  200.  
  201. /*****************************************/
  202.  
  203.  
  204. void x_record_arc (displaylist, action, x, y, width, height,
  205.            startangle, arcangle,
  206.            function, color, linewidth)
  207.  
  208. ListHeader *displaylist;
  209. Action action;
  210. long x, y, width, height, startangle, arcangle;
  211. unsigned long function, color, linewidth;
  212.  
  213. {
  214.     Arc * elt;
  215.  
  216.     elt = (Arc *) AllocDisplayElt ();
  217.     elt->action = action;
  218.     elt->x = x;
  219.     elt->y = y;
  220.     elt->width = width;
  221.     elt->height = height;
  222.     elt->startangle = startangle;
  223.     elt->arcangle = arcangle;
  224.     elt->function = function;
  225.     elt->color = color;
  226.     elt->linewidth = linewidth;
  227.     List_Append (displaylist, (Ref) elt);
  228. }
  229.  
  230. /*****************************************/
  231.  
  232.  
  233. void x_record_rectangle (displaylist, action, x, y, width, height,
  234.              function, color, linewidth)
  235.  
  236. ListHeader *displaylist;
  237. Action action;
  238. long x, y, width, height;
  239. unsigned long function, color, linewidth;
  240.  
  241. {
  242.     Rectangle * elt;
  243.  
  244.     elt = (Rectangle *) AllocDisplayElt ();
  245.     elt->action = action;
  246.     elt->x = x;
  247.     elt->y = y;
  248.     elt->width = width;
  249.     elt->height = height;
  250.     elt->function = function;
  251.     elt->color = color;
  252.     elt->linewidth = linewidth;
  253.     List_Append (displaylist, (Ref) elt);
  254. }
  255.  
  256. /*****************************************/
  257.  
  258.  
  259. void x_record_polygon (displaylist, action, points, npoints,
  260.                function, color, linewidth)
  261.  
  262. ListHeader *displaylist;
  263. Action action;
  264. XPoint *points;
  265. long npoints;
  266. unsigned long function, color, linewidth;
  267.  
  268. {
  269.     Polygon * elt;
  270.     XPoint *p;
  271.  
  272.  
  273.     elt = (Polygon *) AllocDisplayElt ();
  274.     elt->action = action;
  275.     elt->npoints = npoints;
  276.     elt->points = p = (XPoint *) malloc (npoints*2*sizeof(short));
  277.     for (; npoints > 0; npoints--, p++, points++)
  278.         *p = *points;
  279.     elt->function = function;
  280.     elt->color = color;
  281.     elt->linewidth = linewidth;
  282.     List_Append (displaylist, (Ref) elt);
  283. }
  284.  
  285. /*****************************************/
  286.  
  287.  
  288. void x_record_string (displaylist, action, x, y, str, font,
  289.               function, color)
  290.  
  291. ListHeader *displaylist;
  292. Action action;
  293. long x, y, font;
  294. char *str;
  295. unsigned long function, color;
  296.  
  297. {
  298.     String * elt;
  299.  
  300.     elt = (String *) AllocDisplayElt ();
  301.     elt->action = action;
  302.     elt->x = x;
  303.     elt->y = y;
  304.     elt->str = (char *) malloc (strlen (str)+1); /* 11.9 */
  305.     strcpy (elt->str, str);
  306.     *(elt->str+strlen(str)) = '\0';
  307.     elt->function = function;
  308.     elt->color = color;
  309.     elt->font = font;
  310.     List_Append (displaylist, (Ref) elt);
  311. }
  312.  
  313. /*****************************************/
  314.  
  315.  
  316. static long x_draw_elt (elt, g)
  317.  
  318. DisplayElt *elt;
  319. GraphicClosure *g;
  320.  
  321. {
  322.     Line *line;
  323.     Arc *arc;
  324.     Rectangle *rectangle;
  325.     String *s;
  326.     Polygon *polygon;
  327.  
  328.  
  329.     switch (elt->action)
  330.     {
  331.         case DRAW_LINE:
  332.         line = (Line *) elt;
  333.         x_set_gc (g->display, g->gc, line->function,
  334.               line->color, line->linewidth, xDefaultFont);
  335.         XDrawLine (g->display, g->drawable, g->gc,
  336.                line->x0, line->y0, line->x1, line->y1);
  337.         break;
  338.  
  339.         case DRAW_ARC:
  340.         case FILL_ARC:
  341.         arc = (Arc *) elt;
  342.         x_set_gc (g->display, g->gc, arc->function,
  343.               arc->color, arc->linewidth, xDefaultFont);
  344.         if (arc->action == DRAW_ARC)
  345.             XDrawArc (g->display, g->drawable, g->gc,
  346.               arc->x, arc->y, 
  347.               arc->width, arc->height,
  348.               arc->startangle, arc->arcangle);
  349.         else
  350.             XFillArc (g->display, g->drawable, g->gc,
  351.               arc->x, arc->y, 
  352.               arc->width, arc->height,
  353.               arc->startangle, arc->arcangle);
  354.         break;
  355.  
  356.         case DRAW_RECTANGLE:
  357.         case FILL_RECTANGLE:
  358.         rectangle = (Rectangle *) elt;
  359.         x_set_gc (g->display, g->gc, rectangle->function,
  360.               rectangle->color, rectangle->linewidth, xDefaultFont);
  361.         if (rectangle->action == DRAW_RECTANGLE)
  362.             XDrawRectangle (g->display, g->drawable, g->gc,
  363.                 rectangle->x, rectangle->y, 
  364.                 rectangle->width, rectangle->height);
  365.         else
  366.             XFillRectangle (g->display, g->drawable, g->gc,
  367.                 rectangle->x, rectangle->y, 
  368.                 rectangle->width, rectangle->height);
  369.         break;
  370.  
  371.         case DRAW_STRING:
  372.         case DRAW_IMAGE_STRING:
  373.         s = (String *) elt;
  374.         x_set_gc (g->display, g->gc, s->function,
  375.               s->color, xDefaultLineWidth, s->font);
  376.         if (s->action == DRAW_STRING)
  377.             XDrawString (g->display, g->drawable, g->gc,
  378.                  s->x, s->y, 
  379.                  s->str, strlen (s->str));
  380.         else
  381.             XDrawImageString (g->display, g->drawable, g->gc,
  382.                  s->x, s->y, 
  383.                  s->str, strlen (s->str));
  384.         break;
  385.  
  386.         case DRAW_POLYGON:
  387.         case FILL_POLYGON:
  388.         polygon = (Polygon *) elt;
  389.         x_set_gc (g->display, g->gc, polygon->function,
  390.               polygon->color, polygon->linewidth, xDefaultFont);
  391.         if (polygon->action == FILL_POLYGON)
  392.             XFillPolygon (g->display, g->drawable, g->gc,
  393.                   polygon->points, polygon->npoints,
  394.                   Complex, CoordModeOrigin);
  395.         else
  396.             XDrawLines   (g->display, g->drawable, g->gc,
  397.                   polygon->points, polygon->npoints,
  398.                   CoordModeOrigin);
  399.         break;
  400.  
  401.     }
  402.  
  403.     return TRUE;
  404. }
  405.  
  406. /*****************************************/
  407.  
  408. /* note if we have not been able to create a pixmap for the window,
  409.    then the pixmap is the window itself, and the pixmapgc is the gc of the window.
  410.    - jch - Thu Aug  6 16:58:22 MET DST 1992
  411. */
  412.  
  413. void x_refresh_window (display, window, pixmap, pixmapgc, displaylist)
  414.  
  415. Display *display;
  416. Window window;
  417. Pixmap pixmap;
  418. GC pixmapgc;
  419. ListHeader *displaylist;
  420.  
  421. {
  422.     XWindowAttributes attr;
  423.     GraphicClosure g;
  424.  
  425.  
  426.     /* disable the GraphicsExpose emitted by XCopyArea */
  427.     XSetGraphicsExposures (display, pixmapgc, False);
  428.  
  429.     /* get the geometry of the window */
  430.     XGetWindowAttributes (display, window, &attr);
  431.  
  432. #if 0
  433.     /* does not work with a pixmap, only with windows !! @#@^&%#(*&! - jch */
  434.     XClearArea (display, pixmap, 0, 0, 
  435.         attr.width, attr.height, False);
  436. #endif
  437.  
  438.     x_set_gc (display, pixmapgc, GXcopy, attr.backing_pixel,
  439.           xDefaultLineWidth, xDefaultFont);
  440.  
  441.     XFillRectangle (display, pixmap, pixmapgc,
  442.             0, 0, attr.width, attr.height);
  443.  
  444.     g.display = display;
  445.     g.drawable = pixmap;
  446.     g.gc = pixmapgc;
  447.  
  448.     List_Enum (displaylist, x_draw_elt, &g);
  449.  
  450.  
  451.     if (window != pixmap)
  452.         XCopyArea (display, pixmap, window, pixmapgc, 0, 0, 
  453.            attr.width, attr.height, 0, 0);
  454.  
  455.     XSync (display, 0);
  456. }
  457.  
  458. /*****************************************/
  459.  
  460. static long x_free_elt (elt, closure)
  461.  
  462. DisplayElt *elt;
  463. long *closure;
  464.  
  465. {
  466.     Line *line;
  467.     Arc *arc;
  468.     Rectangle *rectangle;
  469.     String *s;
  470.     Polygon *polygon;
  471.  
  472.  
  473.     /* free the attributes of the element */
  474.     switch (elt->action)
  475.     {
  476.         case DRAW_LINE:
  477.         /* no attribute to free ? */
  478.         break;
  479.  
  480.         case DRAW_ARC:
  481.         case FILL_ARC:
  482.         /* no attribute to free ? */
  483.         break;
  484.  
  485.         case DRAW_RECTANGLE:
  486.         case FILL_RECTANGLE:
  487.         /* no attribute to free ? */
  488.         break;
  489.  
  490.         case DRAW_STRING:
  491.         case DRAW_IMAGE_STRING:
  492.         s = (String *) elt;
  493.         free (s->str);
  494.         break;
  495.  
  496.         case DRAW_POLYGON:
  497.         case FILL_POLYGON:
  498.         polygon = (Polygon *) elt;
  499.         free (polygon->points);
  500.         break;
  501.  
  502.     }
  503.  
  504.     /* finaly, free the element itself */
  505.     FreeDisplayElt (elt);
  506.     
  507.     return TRUE;
  508. }
  509.  
  510. /*****************************************/
  511.  
  512. void x_free_display_list (displaylist)
  513.  
  514. ListHeader *displaylist;
  515.  
  516. {
  517.     List_Enum (displaylist, x_free_elt, NULL);
  518. }
  519.  
  520. /*****************************************/
  521.  
  522. static char *prolog[] = {
  523.     "%!PS-Adobe-2.0\n",
  524.     "/mt {moveto} def /lt {lineto} def /slw {setlinewidth} def\n",
  525.     "/np {newpath} def /st {stroke} def /fi {fill} def /cp {closepath} def\n",
  526.     "1 setlinecap 1 setlinejoin\n",
  527.     "/line {/lw exch def /b exch def /g exch def /r exch def\n",
  528.     "       /y1 exch def /x1 exch def \n",
  529.     "       /y0 exch def /x0 exch def\n",
  530.     "       r 65535 div g 65535 div b 65535 div setrgbcolor\n",
  531.     "       np lw slw x0 y0 mt x1 y1 lt st} def\n",
  532.     "/rect {/sf exch def /lw exch def\n",
  533.     "       /b exch def /g exch def /r exch def\n",
  534.     "       /h exch def /w exch def \n",
  535.     "       /y exch def /x exch def\n",
  536.     "       r 65535 div g 65535 div b 65535 div setrgbcolor\n",
  537.     "       np lw slw x y mt x w add y lt x w add y h sub lt\n",
  538.     "       x y h sub lt cp sf {st} {fi} ifelse} def\n",
  539.     "/earcdict 100 dict def\n", /* see cookbook ex #3 */
  540.     "earcdict /mtrx matrix put\n",
  541.     "/earc {earcdict begin\n",
  542.     "       /sf exch def /lw exch def\n",
  543.     "       /b exch def /g exch def /r exch def\n",
  544.     "       r 65535 div g 65535 div b 65535 div setrgbcolor\n",
  545.     "       /ea exch def /sa exch def\n",
  546.     "       /yr exch def /xr exch def /y exch def /x exch def\n",
  547.     "       /savematrix mtrx currentmatrix def\n",
  548.     "       np x y translate xr yr scale 0 0 1 sa ea arc\n",
  549.     "       savematrix setmatrix lw slw sf {st} {fi} ifelse\n",
  550.     "       end} def\n",
  551.     "/Helvetica findfont 18 scalefont setfont\n",
  552.     "/dstr {/sf exch def\n",
  553.     "       /b exch def /g exch def /r exch def\n",
  554.     "       /str exch def /y exch def /x exch def\n",
  555.     "       r 65535 div g 65535 div b 65535 div setrgbcolor\n",
  556.     "       x y mt str show} def\n",
  557.     0
  558. };
  559.  
  560.  
  561. static void x_postscript_prolog (f)
  562.  
  563. long f;
  564.  
  565. {
  566.     long i;
  567.  
  568.     for (i = 0; prolog[i] != 0; i++)
  569.         write (f, prolog[i], strlen (prolog[i]));
  570. }
  571.  
  572. /*****************************************/
  573.  
  574. #define BUF_SIZE 512
  575.  
  576. static char nstr[BUF_SIZE];
  577.  
  578. static char *add_number (buf, n)
  579.  
  580. char *buf;
  581. long n;
  582.  
  583. {
  584.     long m, i;
  585.     char *s;
  586.  
  587.     for (m=n, i=1; m>=10; i++)
  588.         m /= 10;
  589.  
  590.     if (i < BUF_SIZE && strlen (buf) + i < BUF_SIZE)
  591.     {
  592.     sprintf (nstr, "%ld ", n);
  593.     strcat (buf, nstr);
  594.     }
  595.  
  596.     return buf;
  597. }
  598.  
  599.  
  600. static char *add_string (buf, s)
  601.  
  602. char *buf, *s;
  603.  
  604. {
  605.     if (strlen (buf) + strlen(s) < BUF_SIZE)
  606.     strcat (buf, s);
  607.  
  608.     return buf;
  609. }
  610.  
  611.  
  612. static void x_get_rgb_values (display, window, color, rgb)
  613.  
  614.      Display *display;
  615.      Window window;
  616.      unsigned long color;
  617.      XColor *rgb;
  618.  
  619. {
  620.     XWindowAttributes windowAttributes;
  621.  
  622.     XGetWindowAttributes (display, window, &windowAttributes);
  623.     rgb->pixel = color;
  624.     XQueryColor (display, windowAttributes.colormap, rgb);
  625. }
  626.  
  627.  
  628. static long x_postscript_elt (elt, psc)
  629.  
  630. DisplayElt *elt;
  631. PostScriptClosure *psc;
  632.  
  633. {
  634.     Line *line;
  635.     Arc *arc;
  636.     Rectangle *rectangle;
  637.     String *s;
  638.     Polygon *polygon;
  639.     char buf[BUF_SIZE];
  640.     char *pbuf;
  641.     XPoint *p;
  642.     XColor color;
  643.     long i;
  644.  
  645.  
  646.     buf[0] = 0;
  647.     pbuf = buf;
  648.  
  649.     switch (elt->action)
  650.     {
  651.         case DRAW_LINE:
  652.         line = (Line *) elt;
  653.  
  654.         pbuf = add_number (pbuf, line->x0);
  655.         pbuf = add_number (pbuf, psc->height - line->y0);
  656.         pbuf = add_number (pbuf, line->x1);
  657.         pbuf = add_number (pbuf, psc->height - line->y1);
  658.         x_get_rgb_values (psc->display, psc->window, line->color, &color);
  659.         pbuf = add_number (pbuf, color.red);
  660.         pbuf = add_number (pbuf, color.green);
  661.         pbuf = add_number (pbuf, color.blue);
  662.         pbuf = add_number (pbuf, line->linewidth);
  663.         pbuf = add_string (pbuf, "line\n");
  664.         write (psc->f, pbuf, strlen (pbuf));
  665.         break;
  666.  
  667.         case DRAW_RECTANGLE:
  668.         case FILL_RECTANGLE:
  669.         rectangle = (Rectangle *) elt;
  670.  
  671.         pbuf = add_number (pbuf, rectangle->x);
  672.         pbuf = add_number (pbuf, psc->height - rectangle->y);
  673.         pbuf = add_number (pbuf, rectangle->width);
  674.         pbuf = add_number (pbuf, rectangle->height);
  675.         x_get_rgb_values (psc->display, psc->window, rectangle->color, &color);
  676.         pbuf = add_number (pbuf, color.red);
  677.         pbuf = add_number (pbuf, color.green);
  678.         pbuf = add_number (pbuf, color.blue);
  679.  
  680.         if (rectangle->action == DRAW_RECTANGLE)
  681.         {
  682.         pbuf = add_number (pbuf, rectangle->linewidth);
  683.         pbuf = add_string (pbuf, "true ");
  684.         }
  685.         else
  686.         {
  687.         pbuf = add_number (pbuf, 1);
  688.         pbuf = add_string (pbuf, "false ");
  689.         }
  690.  
  691.         pbuf = add_string (pbuf, "rect\n");
  692.         write (psc->f, pbuf, strlen (pbuf));
  693.         break;
  694.  
  695.         case DRAW_ARC:
  696.         case FILL_ARC:
  697.         arc = (Arc *) elt;
  698.         pbuf = add_number (pbuf, arc->x+arc->width/2);
  699.         pbuf = add_number (pbuf, psc->height - (arc->y+arc->height/2));
  700.         pbuf = add_number (pbuf, arc->width/2);
  701.         pbuf = add_number (pbuf, arc->height/2);
  702.         pbuf = add_number (pbuf, arc->startangle);
  703.         pbuf = add_number (pbuf, (arc->startangle+arc->arcangle)/64);
  704.         x_get_rgb_values (psc->display, psc->window, arc->color, &color);
  705.         pbuf = add_number (pbuf, color.red);
  706.         pbuf = add_number (pbuf, color.green);
  707.         pbuf = add_number (pbuf, color.blue);
  708.  
  709.         if (arc->action == DRAW_ARC)
  710.         {
  711.         pbuf = add_number (pbuf, arc->linewidth);
  712.         pbuf = add_string (pbuf, "true ");
  713.         }
  714.         else
  715.         {
  716.         pbuf = add_number (pbuf, 1);
  717.         pbuf = add_string (pbuf, "false ");
  718.         }
  719.  
  720.         pbuf = add_string (pbuf, "earc\n");
  721.         write (psc->f, pbuf, strlen (pbuf));
  722.         break;
  723.  
  724.         case DRAW_STRING:
  725.         case DRAW_IMAGE_STRING:
  726.         s = (String *) elt;
  727.         pbuf = add_number (pbuf, s->x);
  728.         pbuf = add_number (pbuf, psc->height - s->y);
  729.         pbuf = add_string (pbuf, "(");
  730.         pbuf = add_string (pbuf, s->str);
  731.         pbuf = add_string (pbuf, ") ");
  732.         x_get_rgb_values (psc->display, psc->window, s->color, &color);
  733.         pbuf = add_number (pbuf, color.red);
  734.         pbuf = add_number (pbuf, color.green);
  735.         pbuf = add_number (pbuf, color.blue);
  736.  
  737.         if (s->action == DRAW_STRING)
  738.         pbuf = add_string (pbuf, "true ");
  739.         else
  740.         pbuf = add_string (pbuf, "false ");
  741.  
  742.         pbuf = add_string (pbuf, "dstr\n");
  743.         write (psc->f, pbuf, strlen (pbuf));
  744.         break;
  745.  
  746.         case FILL_POLYGON:
  747.         polygon = (Polygon *) elt;
  748.  
  749.         x_get_rgb_values (psc->display, psc->window, polygon->color, &color);
  750.         pbuf = add_number (pbuf, color.red);
  751.         pbuf = add_string (pbuf, "65535 div ");
  752.         pbuf = add_number (pbuf, color.green);
  753.         pbuf = add_string (pbuf, "65535 div ");
  754.         pbuf = add_number (pbuf, color.blue);
  755.         pbuf = add_string (pbuf, "65535 div ");
  756.         pbuf = add_string (pbuf, "setrgbcolor ");
  757.  
  758.         p = polygon->points;
  759.         pbuf = add_string (pbuf, "np ");
  760.         pbuf = add_number (pbuf, p->x);
  761.         pbuf = add_number (pbuf, psc->height - p->y);
  762.         pbuf = add_string (pbuf, "mt\n");
  763.         ++p;
  764.         for (i=1; i<polygon->npoints; i++, p++)
  765.         {
  766.         pbuf = add_number (pbuf, p->x);
  767.         pbuf = add_number (pbuf, psc->height - p->y);
  768.         pbuf = add_string (pbuf, "lt ");
  769.         if (i%4==0)
  770.             pbuf = add_string (pbuf, "\n");
  771.         }
  772.  
  773.         pbuf = add_string (pbuf, "cp fi\n");
  774.         write (psc->f, pbuf, strlen (pbuf));
  775.         break;
  776.     }
  777.  
  778.     return TRUE;
  779. }
  780.  
  781. /*****************************************/
  782.  
  783.  
  784. long x_postscript_window (display, window, displaylist, filename)
  785.  
  786.      Display *display;
  787.      Window window;
  788.      ListHeader *displaylist;
  789.      char *filename;
  790.  
  791. {
  792.     XWindowAttributes windowAttributes;
  793.     PostScriptClosure psc;
  794.  
  795.  
  796.     psc.display =(long)display;
  797.     psc.window = window;
  798.     if ((psc.f = open (filename, O_CREAT|O_WRONLY|O_TRUNC, 
  799.            S_IRUSR|S_IWUSR|S_IRWXG)) == -1)
  800.     {
  801.     Errorline ("\n*** Error: cannot open file %s.\n", filename);
  802.     return FALSE;
  803.     }
  804.     
  805.     XGetWindowAttributes (display, window, &windowAttributes);
  806.     psc.height = windowAttributes.height;
  807.     x_postscript_prolog (psc.f);
  808.     List_Enum (displaylist, x_postscript_elt, &psc);
  809.     write (psc.f, "showpage\n", strlen ("showpage\n"));
  810.     close (psc.f);
  811.  
  812.     return TRUE;
  813. }
  814.  
  815. /*****************************************/
  816.  
  817. #endif
  818.