1 
2 
3 /*
4  *  Author: Arvin Schnell
5  */
6 
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <math.h>
11 #include <limits.h>
12 
13 #include <X11/Xlib.h>
14 #ifdef DBE
15 #  include <X11/extensions/Xdbe.h>
16 #endif
17 
18 #include "Trans.h"
19 #include "Scope.h"
20 #include "Sample.h"
21 #include "main.h"
22 #include "utils.h"
23 
24 
Scope()25 Scope::Scope ()
26 {
27     realized = false;
28 
29     zoom = 0.0;
30 
31     drawing_mode = SINGLEBIT;	// FIXME
32     draw_cross = false;		// FIXME
33     num_count = 1;		// FIXME
34 }
35 
36 
37 void
allocbuffer()38 Scope::allocbuffer ()
39 {
40     XtGCMask gc_mask = 0;
41     XGCValues gc_values;
42 
43     switch (drawing_mode) {
44 
45 	case SINGLEBIT:
46 	    pixmap = XCreatePixmap (display, window, width, height, 1);
47 	    pixmapGC = XCreateGC (display, pixmap, gc_mask, &gc_values);
48 	    break;
49 
50 	case FULLBIT:{
51 	    int depth = DefaultDepth (display, DefaultScreen (display));
52 	    pixmap = XCreatePixmap (display, window, width, height, depth);
53 	    pixmapGC = XCreateGC (display, pixmap, gc_mask, &gc_values);
54 	}
55 	break;
56 
57 #ifdef DBE
58 	case DOUBLEBUFFER:
59 	    dbeBuffer = XdbeAllocateBackBufferName (display, window, XdbeUntouched);
60 	    dbeGC = XCreateGC (display, window, gc_mask, &gc_values);
61 	    break;
62 #endif
63 
64     }
65 }
66 
67 
68 void
freebuffer()69 Scope::freebuffer ()
70 {
71     switch (drawing_mode) {
72 
73 	case SINGLEBIT:
74 	    XFreePixmap (display, pixmap);
75 	    XFreeGC (display, pixmapGC);
76 	    break;
77 
78 	case FULLBIT:
79 	    XFreePixmap (display, pixmap);
80 	    XFreeGC (display, pixmapGC);
81 	    break;
82 
83 #ifdef DBE
84 	case DOUBLEBUFFER:
85 	    XdbeDeallocateBackBufferName (display, dbeBuffer);
86 	    XFreeGC (display, dbeGC);
87 	    break;
88 #endif
89 
90     }
91 }
92 
93 
94 void
clearbuffer()95 Scope::clearbuffer ()
96 {
97     switch (drawing_mode) {
98 
99 	case SINGLEBIT:
100 	    XSetForeground (display, pixmapGC, 0);
101 	    XFillRectangle (display, pixmap, pixmapGC, 0, 0, width, height);
102 	    break;
103 
104 	case FULLBIT:
105 	    XSetForeground (display, pixmapGC, xanalyser.backgroundcolor);
106 	    XFillRectangle (display, pixmap, pixmapGC, 0, 0, width, height);
107 	    break;
108 
109 #ifdef DBE
110 	case DOUBLEBUFFER:
111 	    XSetForeground (display, dbeGC, xanalyser.backgroundcolor);
112 	    XFillRectangle (display, dbeBuffer, dbeGC, 0, 0, width, height);
113 	    break;
114 #endif
115 
116     }
117 }
118 
119 
120 void
resize(bool redraw)121 Scope::resize (bool redraw)
122 {
123     if (!realized)
124 	return;
125 
126     freebuffer ();
127 
128     myXGetDrawableSize (display, window, &width, &height);
129     K.setB (0, height, width, 0);
130 
131     allocbuffer ();
132     clearbuffer ();
133 
134     if (redraw) {
135 	XRectangle rect = { 0, 0, static_cast<unsigned short>(width), static_cast<unsigned short>(height) };
136 	draw (rect);
137     }
138 }
139 
140 
141 bool
realize(Display * display,Window window)142 Scope::realize (Display* display, Window window)
143 {
144     if (realized)
145 	return false;
146     realized = true;
147 
148     Scope::display = display;
149     Scope::window = window;
150 
151     myXGetDrawableSize (display, window, &width, &height);
152 
153     XtGCMask gc_mask = 0;
154     XGCValues gc_values;
155 
156     windowGC = XCreateGC (display, window, gc_mask, &gc_values);
157     K.setA (-1.0, -1.0, +1.0, +1.0);
158     K.setB (0, height, width, 0);
159 
160     allocbuffer ();
161     clearbuffer ();
162 
163     xpts = new XPoint[sample.length];
164 
165     return true;
166 }
167 
168 
169 bool
destroy()170 Scope::destroy ()
171 {
172     if (!realized)
173 	return false;
174 
175     XFreeGC (display, windowGC);
176 
177     freebuffer ();
178 
179     delete[] xpts;
180 
181     realized = false;
182 
183     return true;
184 }
185 
186 
187 void
clear(bool drawit)188 Scope::clear (bool drawit)
189 {
190     if (!realized)
191 	return;
192 
193     clearbuffer ();
194 
195     if (drawit) {
196 	XRectangle rect = { 0, 0, static_cast<unsigned short>(width), static_cast<unsigned short>(height) };
197 	draw (rect);
198     }
199 }
200 
201 
202 void
draw(XRectangle rect)203 Scope::draw (XRectangle rect)
204 {
205     XSetClipRectangles (display, windowGC, 0, 0, &rect, 1, Unsorted);
206 
207     int w2 = width / 2;
208     int h2 = height / 2;
209     int l = (width + height) / 32;
210 
211     switch (drawing_mode) {
212 
213 	case SINGLEBIT:
214 	    XSetForeground (display, windowGC, xanalyser.datacolor);
215 	    XSetBackground (display, windowGC, xanalyser.backgroundcolor);
216 	    XCopyPlane (display, pixmap, window, windowGC, 0, 0, width, height,
217 			0, 0, 1);
218 	    if (draw_cross) {
219 		XSetForeground (display, windowGC, xanalyser.majorgridcolor);
220 		XDrawLine (display, window, windowGC, w2 - 3 * l, h2 + 3 * l,
221 			   w2 + 3 * l, h2 - 3 * l);
222 		XDrawLine (display, window, windowGC, w2 - l, h2, w2 + l, h2);
223 		XDrawLine (display, window, windowGC, w2, h2 - l, w2, h2 + l);
224 	    }
225 	    break;
226 
227 	case FULLBIT:
228 	    XCopyArea (display, pixmap, window, windowGC, 0, 0, width, height, 0, 0);
229 	    break;
230 
231 #ifdef DBE
232 	case DOUBLEBUFFER:
233 	    XdbeSwapInfo dbeSwapInfo;
234 	    dbeSwapInfo.swap_window = window;
235 	    dbeSwapInfo.swap_action = XdbeUndefined;
236 	    XdbeSwapBuffers (display, &dbeSwapInfo, 1);
237 	    break;
238 #endif
239 
240     }
241 }
242 
243 
244 bool
shot(const int32_t * buffer,bool drawit)245 Scope::shot (const int32_t* buffer, bool drawit)
246 {
247     if (!realized)
248 	return false;
249 
250     if (sample.frame_count % num_count == 0)
251 	clear (0);
252 
253     const double dx = xanalyser.dcadjust ? sample.dc[0] / INT_MAX : 0;
254     const double dy = xanalyser.dcadjust ? sample.dc[1] / INT_MAX : 0;
255 
256     const double sf = M_LOG2E * exp (0.05 * zoom * log (10.0));
257 
258     for (unsigned int i = 0; i < sample.length; i++) {
259 
260 	double x = (double)(buffer[2 * i + 0]) / (double)(INT_MAX) - dx;
261 	double y = (double)(buffer[2 * i + 1]) / (double)(INT_MAX) - dy;
262 
263 	double h = hypot (x, y);
264 	double rdh = h == 0.0 ? 0.0 : sf * log (h + 1.0) / h;
265 
266 	K.AtoB (x * rdh, y * rdh, xpts[i].x, xpts[i].y);
267 
268     }
269 
270     int w2 = width / 2;
271     int h2 = height / 2;
272     int l = (width + height) / 32;
273 
274     switch (drawing_mode) {
275 
276 	case SINGLEBIT:
277 	    XSetForeground (display, pixmapGC, 1);
278 	    XDrawLines (display, pixmap, pixmapGC, xpts, sample.length,
279 			CoordModeOrigin);
280 	    break;
281 
282 	case FULLBIT:
283 	    XSetForeground (display, pixmapGC, xanalyser.datacolor);
284 	    XDrawLines (display, pixmap, pixmapGC, xpts, sample.length,
285 			CoordModeOrigin);
286 	    if (draw_cross) {
287 		XSetForeground (display, pixmapGC, xanalyser.majorgridcolor);
288 		XDrawLine (display, pixmap, pixmapGC, w2 - 3 * l, h2 + 3 * l,
289 			   w2 + 3 * l, h2 - 3 * l);
290 		XDrawLine (display, pixmap, pixmapGC, w2 - l, h2, w2 + l, h2);
291 		XDrawLine (display, pixmap, pixmapGC, w2, h2 - l, w2, h2 + l);
292 	    }
293 	    break;
294 
295 #ifdef DBE
296 	case DOUBLEBUFFER:
297 	    XSetForeground (display, dbeGC, xanalyser.datacolor);
298 	    XDrawLines (display, dbeBuffer, dbeGC, xpts, sample.length,
299 			CoordModeOrigin);
300 	    if (draw_cross) {
301 		XSetForeground (display, dbeGC, xanalyser.majorgridcolor);
302 		XDrawLine (display, dbeBuffer, dbeGC, w2 - 3 * l, h2 + 3 * l,
303 			   w2 + 3 * l, h2 - 3 * l);
304 		XDrawLine (display, dbeBuffer, dbeGC, w2 - l, h2, w2 + l, h2);
305 		XDrawLine (display, dbeBuffer, dbeGC, w2, h2 - l, w2, h2 + l);
306 	    }
307 	    break;
308 #endif
309 
310     }
311 
312     if (drawit && sample.frame_count % num_count == num_count - 1) {
313 	XRectangle rect = { 0, 0, static_cast<unsigned short>(width), static_cast<unsigned short>(height) };
314 	draw (rect);
315     }
316 
317     return true;
318 }
319 
320 
321 void
set_zoom(double zoom)322 Scope::set_zoom (double zoom)
323 {
324     Scope::zoom = zoom;
325 }
326