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