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 /*
23  * This is intended to be a cheap looking LCD display panel.
24  */
25 #include "brightoninternals.h"
26 #include "brightonkeymappings.h"
27 
28 /*
29  * Use of this variable means every display must have the same coloration
30  */
31 
32 int
destroyDisplay(brightonDevice * dev)33 destroyDisplay(brightonDevice *dev)
34 {
35 	printf("destroyDisplay()\n");
36 
37 	if (dev->image)
38 		brightonFreeBitmap(dev->bwin, dev->image);
39 
40 	dev->image = NULL;
41 
42 	return(0);
43 }
44 
45 static void
renderDot(brightonDevice * dev,int xoff,int yoff,int onoff,int dsize)46 renderDot(brightonDevice *dev, int xoff, int yoff, int onoff, int dsize)
47 {
48 	int xcount = dsize, ycount = dsize, color;
49 
50 	if (onoff == 1) {
51 		color = dev->lastvalue;
52 	} else {
53 		color = dev->value2;
54 	}
55 
56 	while (ycount--)
57 	{
58 		while (xcount--)
59 		{
60 			if (yoff + xoff + xcount >= dev->width * dev->height)
61 				return;
62 			dev->image->pixels[yoff + xoff + xcount] = color;
63 		}
64 		xcount = dsize;
65 		yoff += dev->width;
66 	}
67 }
68 
69 static int
renderChar(brightonDevice * dev,char ch,int xoffset,int dsize,int dspace)70 renderChar(brightonDevice *dev, char ch, int xoffset, int dsize, int dspace)
71 {
72 	int yoff = dev->width, boff, xoff = xoffset;
73 	unsigned char bitmask = 0x80, btarget;
74 
75 	if ((ch = key[(int) ch].map) == -1)
76 		ch = 0;
77 
78 	if ((((key[(int) ch].width + 1) * dsize + dspace) + xoff) >= dev->width)
79 		return(key[(int) ch].width + dsize);
80 
81 	btarget = bitmask >> key[(int) ch].width;
82 
83 	/*
84 	 * We now attempt to render the character - we have the space we need.
85 	 *
86 	 * If any given bit is set in the character mapping then we paint in a
87 	 * dot of size dsize.
88 	 */
89 	for (boff = 0; boff < KEY_HEIGHT; boff++)
90 	{
91 		while ((bitmask & btarget) == 0)
92 		{
93 			if (key[(int) ch].bitmap[boff] & bitmask)
94 			{
95 				renderDot(dev, xoff, yoff, BIT_ON, dsize);
96 			} else {
97 				renderDot(dev, xoff, yoff, BIT_OFF, dsize);
98 			}
99 			xoff += dsize + dspace;
100 			bitmask >>= 1;
101 		}
102 		renderDot(dev, xoff, yoff, BIT_OFF, dsize);
103 		yoff += (dev->width * (dsize + dspace));
104 		xoff = xoffset;
105 		bitmask = 0x80;
106 	}
107 	return((key[(int) ch].width + 1) * (dspace + dsize));
108 }
109 
110 static void
renderText(brightonDevice * dev,char * text)111 renderText(brightonDevice *dev, char *text)
112 {
113 	int dotsize = 1, dotspace = 1, xoffset = 1;
114 	char ch;
115 
116 	if ((text == (char *) 0) || (text == (char *) -1))
117 		return;
118 
119 	if (dev->height < 7) {
120 		dotspace = 0;
121 	} else if (dev->height < 12) {
122 		dotspace = 0;
123 	} else if (dev->height >= 17) {
124 		dotsize = (dev->height - 6) / 5;
125 	}
126 
127 	while ((ch = *text++) != '\0')
128 	{
129 		if ((xoffset += renderChar(dev, ch, xoffset, dotsize, dotspace))
130 			>= dev->width)
131 			return;
132 	}
133 	/*
134 	 * Clear out any remaining text by rendering spaces.
135 	 */
136 	while ((xoffset += renderChar(dev, ' ', xoffset, dotsize, dotspace))
137 		< dev->width)
138 	{
139 		;
140 	}
141 }
142 
143 static int
displaydisplay(brightonDevice * dev)144 displaydisplay(brightonDevice *dev)
145 {
146 	if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN)
147 		return(-1);
148 
149 	if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
150 		& BRIGHTON_WITHDRAWN)
151 		return(-1);
152 
153 	renderText(dev, &dev->text[0]);
154 /*	renderText(dev, "test"); */
155 	/*
156 	 * We should render any text we desire into the bmap, and then have it
157 	 * painted
158 	 */
159 	brightonRender(dev->bwin, dev->image,
160 		/*dev->bwin->app->resources[dev->panel].canvas, */
161 		/*dev->x, dev->y, */
162 		dev->bwin->dlayer,
163 		dev->x + dev->bwin->app->resources[dev->panel].sx,
164 		dev->y + dev->bwin->app->resources[dev->panel].sy,
165 		dev->width, dev->height, 0);
166 
167 	/*
168 	 * We can consider the alpha layer here.
169 	 */
170 	if (dev->image2 != 0)
171 	{
172 		brightonAlphaLayer(dev->bwin, dev->image2,
173 			dev->bwin->dlayer,
174 			dev->x + dev->bwin->app->resources[dev->panel].sx,
175 			dev->y + dev->bwin->app->resources[dev->panel].sy,
176 			dev->width, dev->height,
177 			dev->position);
178 	}
179 
180 	brightonFinalRender(dev->bwin,
181 		dev->x + dev->bwin->app->resources[dev->panel].sx,
182 		dev->y + dev->bwin->app->resources[dev->panel].sy,
183 		dev->width, dev->height);
184 
185 	return(0);
186 }
187 
188 brightonBitmap *first;
189 
190 static int
configure(brightonDevice * dev,brightonEvent * event)191 configure(brightonDevice *dev, brightonEvent *event)
192 {
193 /*	printf("configureDisplay(%i)\n", event->command); */
194 
195 	if (event->command == -1)
196 		return(-1);
197 
198 	if (event->command == BRIGHTON_RESIZE)
199 	{
200 		int i;
201 
202 		dev->originx = event->x;
203 		dev->originy = event->y;
204 
205 		dev->x = event->x;
206 		dev->y = event->y;
207 		dev->width = event->w;
208 		dev->height = event->h;
209 
210 		brightonfree(dev->image->pixels);
211 		dev->image->width = dev->width;
212 		dev->image->height = dev->height;
213 		dev->image->pixels =
214 			(int *) brightonmalloc(dev->width * dev->height * sizeof(int));
215 		for (i = 0; i < dev->width * dev->height; i++)
216 			dev->image->pixels[i] = dev->value2;
217 		/*
218 		 * We should consider altering the locations structure, so that
219 		 * event dispatching is correct.
220 		brightonLocation(dev->bwin, dev->index,
221 			dev->x, dev->y, dev->width, dev->height);
222 		 */
223 
224 		displaydisplay(dev);
225 
226 		return(0);
227 	}
228 
229 	if (event->command == BRIGHTON_KEYRELEASE)
230 	{
231 	}
232 
233 	if (event->command == BRIGHTON_KEYPRESS)
234 	{
235 		brightonIResource *panel = &dev->bwin->app->resources[dev->panel];
236 
237 		panel->callback(dev->bwin, dev->panel, dev->index, event->key);
238 	}
239 
240 	if (event->command == BRIGHTON_MOTION)
241 	{
242 	}
243 
244 	if (event->command == BRIGHTON_PARAMCHANGE)
245 	{
246 		char *string;
247 
248 		if (event->type != BRIGHTON_MEM)
249 			return(-1);
250 
251 		if ((string = (char *) event->m) == 0)
252 			return(-1);
253 
254 		if (strlen(string) > 64)
255 			string[64] = '\0';
256 
257 		sprintf(&dev->text[0], "%s", string);
258 
259 		displaydisplay(dev);
260 
261 		return(0);
262 	}
263 
264 	return(0);
265 }
266 
267 int *
createDisplay(brightonWindow * bwin,brightonDevice * dev,int index,char * bitmap)268 createDisplay(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap)
269 {
270 /* printf("createDisplay()\n"); */
271 
272 	dev->destroy = destroyDisplay;
273 	dev->configure = configure;
274 	dev->bwin = bwin;
275 
276 	if (dev->image)
277 		brightonFreeBitmap(bwin, dev->image);
278 
279 	if (bwin->app->resources[dev->panel].devlocn[dev->index].image != 0)
280 		dev->image =
281 			bwin->app->resources[dev->panel].devlocn[dev->index].image;
282 	else
283 		dev->image = brightonReadImage(bwin, "bitmaps/digits/display.xpm");
284 
285 	if (dev->image == 0) {
286 		printf("Cannot resolve the bitmap library location\n");
287 		_exit(0);
288 	}
289 	dev->value2 = dev->image->pixels[0];
290 
291 	/*
292 	 * We should take a peek at the second image resource. A display uses no
293 	 * bitmaps, the second may be used as an alpha layer.
294 	 */
295 	if (bwin->app->resources[dev->panel].devlocn[dev->index].image2 != 0)
296 		dev->image2 =
297 			bwin->app->resources[dev->panel].devlocn[dev->index].image2;
298 
299 	initkeys();
300 	/*
301 	 * These will force an update when we first display ourselves.
302 	 */
303 	dev->value = 0;
304 	dev->lastvalue = -1;
305 	dev->lastposition = -1;
306 
307 	/*
308 	 * Need to bury this one in the device itself, not globally. It breaks when
309 	 * we have multiple windows.
310 	 */
311 	if (dev->lastvalue == -1)
312 		dev->lastvalue = brightonGetGC(dev->bwin, 0, 0, 0);
313 
314 	return(0);
315 }
316 
317