File: x_savestate.c

package info (click to toggle)
plotutils 2.4.1-15
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 11,072 kB
  • ctags: 6,952
  • sloc: ansic: 76,305; cpp: 12,402; sh: 8,475; yacc: 2,604; makefile: 894; lex: 144
file content (141 lines) | stat: -rw-r--r-- 5,025 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* This file contains push_state() and pop_state() for XDrawablePlotters
   (and XPlotters).  They supplement the generic behavior of savestate()
   and restorestate(), which create and destroy drawing states on the
   stack.  push_state() constructs X11 GC's (i.e. graphics contexts) for a
   new drawing state.  We copy into them, from each of the current GC's,
   all attributes we're interested in.  pop_state() tears down the GC's. */

#include "sys-defines.h"
#include "extern.h"

void
#ifdef _HAVE_PROTOS
_x_push_state (S___(Plotter *_plotter))
#else
_x_push_state (S___(_plotter))
     S___(Plotter *_plotter;)
#endif
{
  Drawable drawable;
  XGCValues gcv;
      
  /* create the X-specified drawing state elements that are pointers (e.g.,
     GC's or lists) */

  /* determine which if either drawable we'll construct the GC's for */
  if (_plotter->x_drawable1)
    drawable = _plotter->x_drawable1;
  else if (_plotter->x_drawable2)
    drawable = _plotter->x_drawable2;
  else
    drawable = (Drawable)NULL;

  if (drawable != (Drawable)NULL)
    /* prepare GC's for new drawing state, by copying attributes we use */
    {
      unsigned long gcmask_fg, gcmask_fill, gcmask_bg;

      gcmask_fg = 
	/* constant attributes (never altered) */
	GCPlaneMask | GCFunction
	/* drawing attributes set by _x_set_attributes() */
	/* NOTE: we also use GCDashOffset and GCDashList, but Xlib does not
	   support retrieving the dash list from a GC, so we'll copy the
	   dashing style in another (painful) way */
	| GCLineStyle | GCLineWidth | GCJoinStyle | GCCapStyle
	/* other GC elements set by the X Drawable driver */
	| GCForeground | GCFont;
      
      gcmask_fill = 
	/* constant attributes (never altered) */
	GCPlaneMask | GCFunction | GCArcMode 
	/* filling attributes set by _x_set_attributes() */
	| GCFillRule
	/* other GC elements set by the X Drawable driver */
	| GCForeground;
      
      gcmask_bg = 
	/* constant attributes (never altered) */
	GCPlaneMask | GCFunction 
	/* other GC elements set by the X Drawable driver */
	| GCForeground;
      
      /* copy from previous drawing state */

      /* copy GC used for drawing */
      XGetGCValues (_plotter->x_dpy, _plotter->drawstate->previous->x_gc_fg, 
		    gcmask_fg, &gcv);
      _plotter->drawstate->x_gc_fg = XCreateGC (_plotter->x_dpy, drawable, 
						gcmask_fg, &gcv);
      if (gcv.line_style != LineSolid)
	/* copy dash style info from previous state */
	{
	  int i, dash_list_len;
	  char *dash_list;
	  
	  /* add dash style elements to GC used for drawing */
	  XSetDashes (_plotter->x_dpy, _plotter->drawstate->x_gc_fg, 
		      _plotter->drawstate->previous->x_gc_dash_offset, 
		      _plotter->drawstate->previous->x_gc_dash_list,
		      _plotter->drawstate->previous->x_gc_dash_list_len);
	  
	  /* add non-opaque dash style elements */
	  dash_list_len = 
	    _plotter->drawstate->previous->x_gc_dash_list_len;
	  dash_list = (char *)_plot_xmalloc (dash_list_len * sizeof(char));
	  for (i = 0; i < dash_list_len; i++)
	    dash_list[i] =
	      _plotter->drawstate->previous->x_gc_dash_list[i];
	  _plotter->drawstate->x_gc_dash_list = dash_list;
	  
	  /* these two were already added by the copy operation that took
	     place in _g_savestate(), but we'll add them again */
	  _plotter->drawstate->x_gc_dash_list_len = dash_list_len;
	  _plotter->drawstate->x_gc_dash_offset = 
	    _plotter->drawstate->previous->x_gc_dash_offset;
	}
      else
	{
	  _plotter->drawstate->x_gc_dash_list = (char *)NULL;
	  _plotter->drawstate->x_gc_dash_list_len = 0;
	  _plotter->drawstate->x_gc_dash_offset = 0;
	}
      
      /* copy GC used for filling */
      XGetGCValues (_plotter->x_dpy, _plotter->drawstate->previous->x_gc_fill, 
		    gcmask_fill, &gcv);
      _plotter->drawstate->x_gc_fill = XCreateGC (_plotter->x_dpy, drawable, 
						  gcmask_fill, &gcv);
      /* copy GC used for erasing */
      XGetGCValues (_plotter->x_dpy, _plotter->drawstate->previous->x_gc_bg, 
		    gcmask_bg, &gcv);
      _plotter->drawstate->x_gc_bg = XCreateGC (_plotter->x_dpy, drawable, 
						gcmask_bg, &gcv);
    }
}

void
#ifdef _HAVE_PROTOS
_x_pop_state (S___(Plotter *_plotter))
#else
_x_pop_state (S___(_plotter))
     S___(Plotter *_plotter;)
#endif
{
  /* N.B. we do _not_ free _plotter->drawstate->x_font_struct anywhere,
     when restorestate() is invoked on an X Drawable or X Plotter */

  /* Free graphics contexts, if we have them -- and to have them, must have
     at least one drawable (see _x_push_state()). */
  if (_plotter->x_drawable1 || _plotter->x_drawable2)
    {
      /* free the dash list in the X11-specific part of the drawing state */
      if (_plotter->drawstate->x_gc_dash_list_len > 0
	  && _plotter->drawstate->x_gc_dash_list != (char *)NULL)
	free ((char *)_plotter->drawstate->x_gc_dash_list);

      XFreeGC (_plotter->x_dpy, _plotter->drawstate->x_gc_fg);
      XFreeGC (_plotter->x_dpy, _plotter->drawstate->x_gc_fill);
      XFreeGC (_plotter->x_dpy, _plotter->drawstate->x_gc_bg);
    }
}