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