first cut at turnon scripts for EasyTimer v2
[fw/altos] / src / draw / lco-test.c
1 /*
2  * Copyright © 2023 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #define TIMEOUT 50
20
21 #define PASS_KEYS
22 #include "test-frame.c"
23
24 #define BIG_FONT BitstreamVeraSans_Roman_58_font
25 #define VOLT_FONT BitstreamVeraSans_Roman_58_font
26 #define SMALL_FONT BitstreamVeraSans_Roman_12_font
27 #define TINY_FONT BitstreamVeraSans_Roman_12_font
28 #define LOGO_FONT BenguiatGothicStd_Bold_26_font
29
30 #define LABEL_Y         (int16_t) (SMALL_FONT.ascent)
31 #define VALUE_Y         (int16_t) (LABEL_Y + BIG_FONT.ascent + 3)
32 #define BOX_X           2
33 #define PAD_X           90
34 #define BOX_LABEL_X     30
35 #define VOLT_LABEL_X    25
36 #define RSSI_LABEL_X    15
37 #define PAD_LABEL_X     95
38 #define SEP_X           (PAD_X - 10)
39 #define SCAN_X          (WIDTH - 100) / 2
40 #define SCAN_Y          49
41 #define SCAN_HEIGHT     4
42 #define FOUND_Y         63
43 #define FOUND_WIDTH     21
44 #define MAX_VALID       (WIDTH / FOUND_WIDTH)
45
46 static int      box_number = 1;
47 static int      pad_number = 1;
48 static int      do_polys = 1;
49 static int      scan_number = 0;
50
51 static const struct ao_coord trek[] = {
52         { .x = 90, .y = 0 },
53         { .x = 60, .y = 40 },
54         { .x = 90, .y = 20 },
55         { .x = 120, .y = 40 },
56 };
57
58 #define NCOORD_TREK (sizeof(trek)/sizeof(trek[0]))
59
60 static const struct ao_coord donut[] = {
61         { .x = 30, .y = 0 },
62         { .x = 0, .y = 30 },
63         { .x = 30, .y = 60 },
64         { .x = 60, .y = 30 },
65         { .x = 30, .y = 0 },
66         { .x = 30, .y = 10 },
67         { .x = 50, .y = 30 },
68         { .x = 30, .y = 50 },
69         { .x = 10, .y = 30 },
70         { .x = 30, .y = 10 },
71 };
72
73 #define NCOORD_DONUT (sizeof(donut)/sizeof(donut[0]))
74
75 static const struct ao_coord bowtie[] = {
76         { .x = 0, .y = 0 },
77         { .x = 32, .y = 32 },
78         { .x = 0, .y = 32 },
79         { .x = 32, .y = 0 },
80 };
81
82 #define NCOORD_BOWTIE (sizeof(bowtie)/sizeof(bowtie[0]))
83
84 static const struct ao_transform logo_transform = {
85         .x_scale = 48, .x_off = 0,
86         .y_scale = 48, .y_off = 0,
87 };
88
89 static const struct ao_transform bowtie_transform = {
90         .x_scale = 1, .x_off = 50,
91         .y_scale = 1, .y_off = 20,
92 };
93
94 static const float pad_volts = 12.3f;
95 static const float lco_volts = 4.1f;
96 static const int rssi = -30;
97
98 static int      boxes[] = { 1, 2, 3, 5, 8, 11, 13, 17, 19, 23, 29, 31, 37, 62, 97 };
99
100 static int      max_box = 97;
101
102 #define ARRAYSIZE(a)    (sizeof(a) / sizeof((a)[0]))
103
104 static bool
105 valid_box(int box)
106 {
107         size_t i;
108         if (box == 0)
109                 return true;
110         for (i = 0; i < ARRAYSIZE(boxes); i++)
111                 if (boxes[i] == box)
112                         return true;
113         return false;
114 }
115
116 static void
117 next_box(void)
118 {
119         for (int n = box_number + 1; n <= max_box; n++)
120                 if (valid_box(n)) {
121                         box_number = n;
122                         return;
123                 }
124         box_number = 0;
125 }
126
127 static void
128 prev_box(void)
129 {
130         for (int n = box_number - 1; n >= 0; n--)
131                 if (valid_box(n)) {
132                         box_number = n;
133                         return;
134                 }
135         box_number = max_box;
136 }
137
138 static bool redraw_all = true;
139
140 void HandleExpose(Display *dpy, Window win, GC gc)
141 {
142         char    str[64];
143         int     i;
144         int     v;
145         int     last_box;
146         int16_t b;
147
148         if (redraw_all)
149                 ao_rect(&fb, 0, 0, WIDTH, HEIGHT, 0xffffffff, AO_COPY);
150
151         if (do_polys == 1)
152                 current_timeout = TIMEOUT;
153         else
154                 current_timeout = 0;
155         switch (do_polys) {
156         case 1:
157                 if (redraw_all)
158                         ao_logo(&fb, &logo_transform, &LOGO_FONT, 0x00000000, AO_COPY);
159                 else
160                         ao_rect(&fb, 0, SCAN_Y, WIDTH, HEIGHT-SCAN_Y, 0xffffffff, AO_COPY);
161                 if (scan_number) {
162                         ao_rect(&fb, SCAN_X, SCAN_Y, (int16_t) scan_number, SCAN_HEIGHT, 0x00000000, AO_COPY);
163                         b = 0;
164                         v = 0;
165                         last_box = 0;
166                         for (i = scan_number; i > 1; i--) {
167                                 if (valid_box(i)) {
168                                         if (!last_box)
169                                                 last_box = i;
170                                         v++;
171                                         if (v == MAX_VALID)
172                                                 break;
173                                 }
174                         }
175                         for (; i <= scan_number; i++) {
176                                 if (valid_box(i)) {
177                                         sprintf(str, "%02d%s", i, i == last_box ? "" : ",");
178                                         ao_text(&fb, &TINY_FONT, 0 + FOUND_WIDTH * b, FOUND_Y, str, 0x00000000, AO_COPY);
179                                         b++;
180                                 }
181                         }
182                         redraw_all = false;
183                 }
184                 break;
185         case 2:
186                 ao_poly(&fb, trek, NCOORD_TREK, NULL, 0x00000000, AO_COPY);
187                 ao_poly(&fb, donut, NCOORD_DONUT, NULL, 0x00000000, AO_COPY);
188                 break;
189         case 3:
190                 ao_poly(&fb, bowtie, NCOORD_BOWTIE, &bowtie_transform, 0x00000000, AO_COPY);
191                 break;
192         default:
193         case 0:
194                 switch (box_number) {
195                 case 0:
196                         sprintf(str, "%4.1f", lco_volts);
197                         ao_text(&fb, &VOLT_FONT, BOX_X, VALUE_Y, str, 0x00000000, AO_COPY);
198                         ao_text(&fb, &SMALL_FONT, VOLT_LABEL_X, LABEL_Y, "LCO Battery", 0x00000000, AO_COPY);
199                         break;
200                 default:
201                         switch (pad_number) {
202                         case -1:
203                                 sprintf(str, "%4.1f", pad_volts);
204                                 ao_text(&fb, &VOLT_FONT, BOX_X, VALUE_Y, str, 0x00000000, AO_COPY);
205                                 ao_text(&fb, &SMALL_FONT, VOLT_LABEL_X, LABEL_Y, "Pad Battery", 0x00000000, AO_COPY);
206                                 break;
207                         case 0:
208                                 sprintf(str, "%4d", rssi);
209                                 ao_text(&fb, &VOLT_FONT, BOX_X, VALUE_Y, str, 0x00000000, AO_COPY);
210                                 ao_text(&fb, &SMALL_FONT, RSSI_LABEL_X, LABEL_Y, "Signal Strength", 0x00000000, AO_COPY);
211                                 break;
212                         default:
213                                 sprintf(str, "%02d", box_number);
214                                 ao_text(&fb, &BIG_FONT, BOX_X, VALUE_Y, str, 0x00000000, AO_COPY);
215                                 ao_text(&fb, &SMALL_FONT, BOX_LABEL_X, LABEL_Y, "Box", 0x00000000, AO_COPY);
216
217                                 sprintf(str, "%d", pad_number);
218                                 ao_text(&fb, &BIG_FONT, PAD_X, VALUE_Y, str, 0x00000000, AO_COPY);
219                                 ao_text(&fb, &SMALL_FONT, PAD_LABEL_X, LABEL_Y, "Pad", 0x00000000, AO_COPY);
220
221                                 ao_rect(&fb, SEP_X, 0, 2, HEIGHT, 0x00000000, AO_COPY);
222                         }
223                         break;
224                 }
225                 break;
226         }
227
228         DoDisplay(dpy, win, gc);
229 }
230
231 void
232 HandleKeyPress(Display *dpy, Window win, GC gc, XEvent *ev)
233 {
234         char    string[10];
235
236         redraw_all = true;
237         if (XLookupString ((XKeyEvent *) ev, string, sizeof (string), 0, 0) >= 1) {
238                 switch (string[0]) {
239                 case 'q':
240                         exit (0);
241                 case 'p':
242                         if (box_number != 0) {
243                                 pad_number++;
244                                 if (pad_number > 8)
245                                         pad_number = -1;
246                         }
247                         break;
248                 case 'P':
249                         if (box_number != 0) {
250                                 pad_number--;
251                                 if (pad_number < -1)
252                                         pad_number = 8;
253                         }
254                         break;
255                 case 'b':
256                         next_box();
257                         break;
258                 case 'B':
259                         prev_box();
260                         break;
261                 case 'i':
262                         do_polys++;
263                         if (do_polys == 4)
264                                 do_polys = 0;
265                         if (do_polys == 1)
266                                 scan_number = 0;
267                         break;
268                 case 'I':
269                         do_polys--;
270                         if (do_polys < 0)
271                                 do_polys = 4;
272                         if (do_polys == 1)
273                                 scan_number = 0;
274                         break;
275                 case 's':
276                         if (scan_number < 99)
277                                 scan_number++;
278                         break;
279                 case 'S':
280                         if (scan_number > 0)
281                                 scan_number--;
282                         break;
283                 case 'c':
284                         break;
285                 }
286                 HandleExpose(dpy, win, gc);
287         }
288 }
289
290 void
291 HandleKeyRelease(Display *dpy, Window win, GC gc, XEvent *ev)
292 {
293         (void) dpy;
294         (void) win;
295         (void) gc;
296         (void) ev;
297 }
298
299 void
300 HandleTimeout(Display *dpy, Window win, GC gc)
301 {
302         if (do_polys == 1) {
303                 if (scan_number < 99)
304                         scan_number++;
305                 else {
306                         redraw_all = true;
307                         box_number = boxes[0];
308                         pad_number = 1;
309                         do_polys = 0;
310                 }
311                 HandleExpose(dpy, win, gc);
312         }
313 }