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