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