1 /* libwmf ("ipa/x/device.h"): library for wmf conversion
2 Copyright (C) 2000 - various; see CREDITS, ChangeLog, and sources
3
4 The libwmf Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The libwmf Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the libwmf Library; see the file COPYING. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
18
19
20 /* This is called by wmf_play() the *first* time the meta file is played
21 */
wmf_x_device_open(wmfAPI * API)22 static void wmf_x_device_open (wmfAPI* API)
23 { wmf_x_t* ddata = WMF_X_GetData (API);
24
25 XWindowAttributes root_attributes;
26
27 XTextProperty wText;
28 XSizeHints sizehints;
29
30 XSetWindowAttributes attributes;
31
32 unsigned int border;
33
34 unsigned long valuemask;
35
36 static char* default_name = "libwmf (x)";
37
38 WMF_DEBUG (API,"wmf_[x_]device_open");
39
40 if ((!(ddata->x_width > 0)) || (!(ddata->x_height > 0)))
41 { WMF_ERROR (API,"window/pixmap has unset or bad size.");
42 API->err = wmf_E_Glitch;
43 return;
44 }
45
46 if (ddata->flags & WMF_X_DISPLAY_OPEN)
47 { ddata->flags &= ~WMF_X_DISPLAY_CLOSE;
48 ddata->flags &= ~WMF_X_WINDOW_OPEN;
49 ddata->flags &= ~WMF_X_WINDOW_CLOSE;
50 ddata->flags &= ~WMF_X_PIXMAP_OPEN;
51 ddata->flags &= ~WMF_X_PIXMAP_CLOSE;
52
53 ddata->flags &= ~WMF_X_CMAP_DESTROY;
54
55 ddata->display = XOpenDisplay (ddata->display_name);
56
57 if (ddata->display == 0)
58 { WMF_ERROR (API,"unable to open display!");
59 API->err = wmf_E_DeviceError;
60 return;
61 }
62
63 ddata->flags |= WMF_X_DISPLAY_CLOSE;
64 ddata->flags |= WMF_X_WINDOW_OPEN;
65 ddata->flags |= WMF_X_PIXMAP_OPEN;
66 }
67 else /* display already open */
68 { if (ddata->display == 0)
69 { WMF_ERROR (API,"display not open!");
70 API->err = wmf_E_DeviceError;
71 return;
72 }
73 }
74
75 ddata->root = RootWindow (ddata->display,DefaultScreen (ddata->display));
76
77 XGetWindowAttributes (ddata->display,ddata->root,&root_attributes);
78
79 ddata->visual = root_attributes.visual;
80 ddata->depth = root_attributes.depth;
81
82 #if defined(__cplusplus) || defined(c_plusplus)
83 ddata->class = ddata->visual->c_class; /* C++ class of screen (monochrome, etc.) */
84 #else
85 ddata->class = ddata->visual->class; /* class of screen (monochrome, etc.) */
86 #endif
87
88 setup_color (API);
89
90 if (ERR (API))
91 { WMF_DEBUG (API,"bailing...");
92 return;
93 }
94
95 ddata->gc = XCreateGC (ddata->display,ddata->root,0,0);
96
97 if (ddata->gc == 0)
98 { WMF_ERROR (API,"unable to create gc!");
99 API->err = wmf_E_DeviceError;
100 return;
101 }
102
103 XSetForeground (ddata->display,ddata->gc,ddata->white);
104
105 if (ddata->flags & WMF_X_WINDOW_OPEN)
106 { ddata->flags &= ~WMF_X_WINDOW_CLOSE;
107
108 border = 0; /* Default border size. */
109
110 valuemask = 0;
111
112 valuemask |= CWBackPixel;
113 attributes.background_pixel = ddata->white;
114
115 valuemask |= CWColormap;
116 attributes.colormap = ddata->colormap;
117
118 ddata->window = XCreateWindow (ddata->display,ddata->root,0,0,
119 ddata->x_width,ddata->x_height,border,ddata->depth,
120 InputOutput,ddata->visual,valuemask,&attributes);
121
122 if (ddata->window == None)
123 { WMF_ERROR (API,"unable to create window!");
124 API->err = wmf_E_DeviceError;
125 return;
126 }
127
128 ddata->flags |= WMF_X_WINDOW_CLOSE;
129
130 XFillRectangle (ddata->display,ddata->window,ddata->gc,
131 0,0,ddata->x_width,ddata->x_height);
132
133 /* Window manager stuff
134 */
135 if (ddata->window_name == 0) ddata->window_name = default_name;
136 if (ddata->icon_name == 0) ddata->icon_name = default_name;
137
138 XStringListToTextProperty (&(ddata->window_name),1,&wText);
139 XSetWMName (ddata->display,ddata->window,&wText);
140
141 XStringListToTextProperty (&(ddata->icon_name) ,1,&wText);
142 XSetWMIconName (ddata->display,ddata->window,&wText);
143
144 sizehints.flags = PSize;
145
146 sizehints.width = (int) ddata->x_width;
147 sizehints.height = (int) ddata->x_height;
148
149 XSetWMNormalHints (ddata->display,ddata->window,&sizehints);
150
151 XMapWindow (ddata->display,ddata->window);
152 }
153
154 if (ddata->flags & WMF_X_PIXMAP_OPEN)
155 { ddata->flags &= ~WMF_X_PIXMAP_CLOSE;
156
157 ddata->pixmap = XCreatePixmap (ddata->display,ddata->root,
158 ddata->x_width,ddata->x_height,ddata->depth);
159
160 if (ddata->pixmap == None)
161 { WMF_ERROR (API,"unable to create pixmap!");
162 API->err = wmf_E_DeviceError;
163 return;
164 }
165
166 ddata->flags |= WMF_X_PIXMAP_CLOSE;
167
168 XFillRectangle (ddata->display,ddata->pixmap,ddata->gc,
169 0,0,ddata->x_width,ddata->x_height);
170
171 if (ddata->window != None)
172 { XSetWindowBackgroundPixmap (ddata->display,ddata->window,ddata->pixmap);
173 XClearWindow (ddata->display,ddata->window);
174 }
175 }
176
177 XFlush (ddata->display);
178 }
179
180 /* This is called by wmf_api_destroy()
181 */
wmf_x_device_close(wmfAPI * API)182 static void wmf_x_device_close (wmfAPI* API)
183 { wmf_x_t* ddata = WMF_X_GetData (API);
184
185 WMF_DEBUG (API,"wmf_[x_]device_close");
186
187 if (ddata->hatch != None) XFreePixmap (ddata->display,ddata->hatch);
188 if (ddata->brush != None) XFreePixmap (ddata->display,ddata->brush);
189
190 if (ddata->gc) XFreeGC (ddata->display,ddata->gc);
191
192 if (ddata->flags & WMF_X_CMAP_DESTROY) XFreeColormap (ddata->display,ddata->colormap);
193 if (ddata->flags & WMF_X_WINDOW_CLOSE) XDestroyWindow (ddata->display,ddata->window);
194 if (ddata->flags & WMF_X_PIXMAP_CLOSE) XFreePixmap (ddata->display,ddata->pixmap);
195 if (ddata->flags & WMF_X_DISPLAY_CLOSE) XCloseDisplay (ddata->display);
196 }
197
198 /* This is called from the beginning of each play for initial page setup
199 */
wmf_x_device_begin(wmfAPI * API)200 static void wmf_x_device_begin (wmfAPI* API)
201 { wmf_x_t* ddata = WMF_X_GetData (API);
202
203 WMF_DEBUG (API,"wmf_[x_]device_begin");
204
205 setdefaultstyle (API);
206
207 XSetClipMask (ddata->display,ddata->gc,None);
208
209 XSetForeground (ddata->display,ddata->gc,ddata->white);
210
211 if (ddata->window != None)
212 XFillRectangle (ddata->display,ddata->window,ddata->gc,
213 0,0,ddata->x_width,ddata->x_height);
214 if (ddata->pixmap != None)
215 XFillRectangle (ddata->display,ddata->pixmap,ddata->gc,
216 0,0,ddata->x_width,ddata->x_height);
217
218 XFlush (ddata->display);
219 }
220
221 /* This is called from the end of each play for page termination
222 */
wmf_x_device_end(wmfAPI * API)223 static void wmf_x_device_end (wmfAPI* API)
224 { wmf_x_t* ddata = WMF_X_GetData (API);
225
226 WMF_DEBUG (API,"wmf_[x_]device_end");
227
228 XFlush (ddata->display);
229 }
230
231 /* translation & scaling functions
232 */
x_translate(wmfAPI * API,wmfD_Coord d_pt)233 static XPoint x_translate (wmfAPI* API,wmfD_Coord d_pt)
234 { return (x_translate_ft64 (API,d_pt,0));
235 }
236
x_translate_ft64(wmfAPI * API,wmfD_Coord d_pt,FT_Vector * pen)237 static XPoint x_translate_ft64 (wmfAPI* API,wmfD_Coord d_pt,FT_Vector* pen)
238 { wmf_x_t* ddata = WMF_X_GetData (API);
239
240 XPoint x_pt;
241
242 double x;
243 double y;
244
245 x = ((double) d_pt.x - (double) ddata->bbox.TL.x);
246 x /= ((double) ddata->bbox.BR.x - (double) ddata->bbox.TL.x);
247 x *= (double) ddata->x_width;
248
249 y = ((double) d_pt.y - (double) ddata->bbox.TL.y);
250 y /= ((double) ddata->bbox.BR.y - (double) ddata->bbox.TL.y);
251 y *= (double) ddata->x_height;
252
253 x_pt.x = (short) floor (x);
254 x_pt.y = (short) floor (y);
255
256 if (pen)
257 { pen->x = floor ((x - floor (x)) * 64);
258 pen->y = floor ((y - floor (y)) * 64);
259 }
260
261 return (x_pt);
262 }
263
x_width(wmfAPI * API,float wmf_width)264 static float x_width (wmfAPI* API,float wmf_width)
265 { wmf_x_t* ddata = WMF_X_GetData (API);
266
267 double width;
268
269 width = (double) wmf_width * (double) ddata->x_width;
270 width /= ((double) ddata->bbox.BR.x - (double) ddata->bbox.TL.x);
271
272 return ((float) width);
273 }
274
x_height(wmfAPI * API,float wmf_height)275 static float x_height (wmfAPI* API,float wmf_height)
276 { wmf_x_t* ddata = WMF_X_GetData (API);
277
278 double height;
279
280 height = (double) wmf_height * (double) ddata->x_height;
281 height /= ((double) ddata->bbox.BR.y - (double) ddata->bbox.TL.y);
282
283 return ((float) height);
284 }
285