1
2 /*
3 * Diverse Bristol audio routines.
4 * Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include "brightoninternals.h"
23
24 static float winwidth, winheight;
25 static float sx = -1, sy = -1;
26
27 int
destroyTouch(brightonDevice * dev)28 destroyTouch(brightonDevice *dev)
29 {
30 printf("destroyTouch()\n");
31
32 if (dev->image)
33 brightonFreeBitmap(dev->bwin, dev->image);
34 dev->image = NULL;
35
36 return(0);
37 }
38
39 static int
displaytouch(brightonDevice * dev)40 displaytouch(brightonDevice *dev)
41 {
42 brightonIResource *panel;
43 float dv, dv2;
44
45 if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN)
46 return(0);
47
48 panel = &dev->bwin->app->resources[dev->panel];
49
50 if (dev->value < 0)
51 {
52 if ((dev->lastposition >= 0) && (dev->lastposition2 >= 0))
53 {
54 brightonDevUndraw(dev->bwin, dev->bwin->dlayer,
55
56 dev->x + ((int) dev->lastposition2)
57 + dev->bwin->app->resources[dev->panel].sx,
58 dev->y + ((int) dev->lastposition)
59 + dev->bwin->app->resources[dev->panel].sy,
60 dev->image->width, dev->image->height);
61
62 brightonFinalRender(dev->bwin,
63 dev->x + dev->lastposition2
64 + dev->bwin->app->resources[dev->panel].sx,
65 dev->y + dev->lastposition
66 + dev->bwin->app->resources[dev->panel].sy,
67 dev->image->width,
68 dev->image->height);
69
70 return(0);
71 }
72 }
73
74 /*
75 * Build up a smooth position for the pot. We may need to adjust this based
76 * on the to/from values.
77 */
78 if ((dev->value == dev->lastvalue) && (dev->value2 == dev->lastvalue2))
79 return(0);
80
81 dv = dev->value;
82 dv2 = 1 - dev->value2;
83
84 if ((dev->lastposition >= 0) && (dev->lastposition2 >= 0))
85 brightonDevUndraw(dev->bwin, dev->bwin->dlayer,
86 dev->x + ((int) dev->lastposition2)
87 + dev->bwin->app->resources[dev->panel].sx,
88 dev->y + ((int) dev->lastposition)
89 + dev->bwin->app->resources[dev->panel].sy,
90 dev->image->width, dev->image->height);
91
92 brightonFinalRender(dev->bwin,
93 dev->x + dev->lastposition2
94 + dev->bwin->app->resources[dev->panel].sx,
95 dev->y + dev->lastposition
96 + dev->bwin->app->resources[dev->panel].sy,
97 dev->image->width,
98 dev->image->height);
99
100 dev->position = dv * (dev->height - dev->image->height);
101 dev->position2 = dv2 * (dev->width - dev->image->width);
102
103 /*
104 * Only draw fixed number of steps.
105 */
106 brightonRender(dev->bwin, dev->image,
107 dev->bwin->dlayer,
108 (int) (dev->x + dev->position2
109 + dev->bwin->app->resources[dev->panel].sx),
110 (int) (dev->y + dev->position
111 + dev->bwin->app->resources[dev->panel].sy),
112 dev->image->width, dev->image->height,
113 dev->position);
114
115 brightonFinalRender(dev->bwin,
116 dev->x + dev->position2
117 + dev->bwin->app->resources[dev->panel].sx,
118 dev->y + dev->position
119 + dev->bwin->app->resources[dev->panel].sy,
120 dev->image->width,
121 dev->image->height);
122
123 dev->lastvalue = dev->value;
124 dev->lastposition = dev->position;
125 dev->lastvalue2 = dev->value2;
126 dev->lastposition2 = dev->position2;
127
128 return(0);
129 }
130
considercallback(brightonDevice * dev)131 static void considercallback(brightonDevice *dev)
132 {
133 brightonIResource *panel = &dev->bwin->app->resources[dev->panel];
134
135 if ((dev->value < 0) || (dev->value2 < 0))
136 return;
137
138 /*
139 * Due to the co-ordinate system, if we do NOT have the reverse flags
140 * then we need to reverse the value.
141 if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
142 & BRIGHTON_REVERSE) == 0)
143 dev->value = 1.0 - dev->value;
144 */
145
146 if ((dev->lastvalue != dev->value) || (dev->lastvalue2 != dev->value2))
147 {
148 if (panel->devlocn[dev->index].callback)
149 {
150 panel->devlocn[dev->index].callback(dev->bwin, dev->panel,
151 dev->index, 1 - dev->value);
152 panel->devlocn[dev->index].callback(dev->bwin, dev->panel,
153 dev->index + 1, 1 - dev->value2);
154 } else {
155 if (panel->callback)
156 panel->callback(dev->bwin, dev->panel, dev->index,
157 1 - dev->value);
158 if (panel->callback)
159 panel->callback(dev->bwin, dev->panel, dev->index + 1,
160 1 - dev->value2);
161 }
162 }
163 }
164
165 static int
configure(brightonDevice * dev,brightonEvent * event)166 configure(brightonDevice *dev, brightonEvent *event)
167 {
168 /*printf("configureTouch(%i)\n", event->command); */
169
170 if (event->command == -1)
171 return(-1);
172
173 if (event->command == BRIGHTON_RESIZE)
174 {
175 dev->originx = event->x;
176 dev->originy = event->y;
177
178 dev->x = event->x;
179 dev->y = event->y;
180 dev->width = event->w;
181 dev->height = event->h;
182
183 /*
184 * We should now rework our parent understanding of our window, since
185 * it will have altered. NOT NECESSARY FOR SCALE.
186 brightonPanelLocation(dev->bwin,
187 dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height);
188
189 considercallback(dev);
190 */
191
192 /*
193 * Highlights need to be rendered dynamically in displaytouch().
194 renderHighlights(dev->bwin, dev);
195 */
196
197 dev->lastvalue = -1;
198 displaytouch(dev);
199
200 return(0);
201 }
202
203 if (event->command == BRIGHTON_BUTTONRELEASE)
204 {
205 if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
206 & BRIGHTON_CENTER)
207 {
208 dev->value = 0.5;
209 dev->value2 = 0.5;
210
211 considercallback(dev);
212
213 displaytouch(dev);
214 } else {
215 if ((dev->flags & BRIGHTON_WIDE) == 0)
216 dev->value = -1;
217
218 displaytouch(dev);
219 }
220
221 sx = sy = -1;
222
223 return(0);
224 }
225
226 if (event->command == BRIGHTON_MOTION)
227 {
228 if (dev->flags & BRIGHTON_WIDE)
229 {
230 if (sx == -1)
231 {
232 sx = event->x;
233 sy = event->y;
234 }
235 /*printf("aks motion %i %i, %i %i, %i %i: %f\n", */
236 /*event->x, event->y, dev->x, dev->y, winwidth, winheight, dev->value); */
237
238 if ((dev->value = ((float) event->y - sy) / winheight + 0.5) < 0)
239 dev->value = 0;
240 else if (dev->value > 1.0)
241 dev->value = 1.0;
242
243 /*
244 * Our motion started from sx, we should look for a value
245 * such as
246 * sx + event->x / winwidth
247 */
248 if ((dev->value2 = ((float) event->x - sx) / winwidth + 0.5) < 0)
249 dev->value2 = 0;
250 else if (dev->value2 > 1.0)
251 dev->value2 = 1.0;
252
253 /*
254 * Need to to reverse value due to co-ordinate space
255 */
256 dev->value2 = 1.0 - dev->value2;
257 } else {
258 if ((dev->value = (((float) (event->y - dev->y)) / dev->height))
259 < 0)
260 dev->value = 0;
261 else if (dev->value > 1.0)
262 dev->value = 1.0;
263 if ((dev->value2 = (((float) (event->x - dev->x)) / dev->width))
264 < 0)
265 dev->value2 = 0;
266 else if (dev->value2 > 1.0)
267 dev->value2 = 1.0;
268 dev->value2 = 1.0 - dev->value2;
269 }
270
271 /*printf("touch motion %i %i, %i %i, %i %i: %f\n", */
272 /*event->x, event->y, dev->x, dev->y, dev->width, dev->height, dev->value); */
273
274 considercallback(dev);
275
276 displaytouch(dev);
277
278 return(0);
279 }
280 return(0);
281 }
282
283 int *
createTouch(brightonWindow * bwin,brightonDevice * dev,int index,char * bitmap)284 createTouch(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap)
285 {
286 /*printf("createTouch(%s)\n", bitmap); */
287
288 winwidth = bwin->display->width / 2;
289 winheight = bwin->display->height / 2;
290
291 dev->destroy = destroyTouch;
292 dev->configure = configure;
293 dev->index = index;
294
295 dev->bwin = bwin;
296
297 /*
298 * Notch has been reused, should give it another name here
299 */
300 if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
301 & BRIGHTON_WIDE)
302 dev->flags |= BRIGHTON_WIDE;
303
304 if (bitmap == 0)
305 {
306 if (dev->image)
307 brightonFreeBitmap(bwin, dev->image);
308
309 /*
310 * Open the default bitmap
311 */
312 if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0)
313 dev->image =
314 bwin->app->resources[dev->panel].devlocn[dev->index].image;
315 if (dev->image == 0)
316 dev->image = brightonReadImage(bwin, "bitmaps/images/pointer.xpm");
317 } else {
318 if (dev->image)
319 brightonFreeBitmap(bwin, dev->image);
320 dev->image = brightonReadImage(bwin, bitmap);
321 if (dev->image == 0)
322 dev->image = brightonReadImage(bwin, "bitmaps/images/pointer.xpm");
323 }
324
325 /*
326 * These will force an update when we first display ourselves.
327 */
328 if (bwin->app->resources[dev->panel].devlocn[dev->index].flags
329 & BRIGHTON_CENTER)
330 {
331 dev->value = 0.5;
332 dev->value2 = 0.5;
333 } else
334 dev->value = 0;
335
336 if (dev->flags & BRIGHTON_WIDE)
337 {
338 dev->value = 0.5;
339 dev->value2 = 0.5;
340 }
341 else
342 dev->value = -1;
343
344 dev->lastvalue = -1;
345 dev->lastposition = 0;
346 dev->lastvalue2 = -1;
347 dev->lastposition2 = 0;
348
349 return(0);
350 }
351
352