351927ee39b3fabbac3df8d61fbcfe15830e6471
[fw/altos] / altosui / Altos.java
1 /*
2  * Copyright © 2010 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; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package altosui;
19
20 import java.awt.*;
21 import java.util.*;
22 import java.text.*;
23 import java.nio.charset.Charset;
24
25 import libaltosJNI.*;
26
27 import org.altusmetrum.AltosLib.*;
28
29 public class Altos extends AltosLib {
30
31         static final int tab_elt_pad = 5;
32
33         static Font label_font;
34         static Font value_font;
35         static Font status_font;
36         static Font table_label_font;
37         static Font table_value_font;
38
39         final static int font_size_small = 1;
40         final static int font_size_medium = 2;
41         final static int font_size_large = 3;
42
43         static void set_fonts(int size) {
44                 int     brief_size;
45                 int     table_size;
46                 int     status_size;
47
48                 switch (size) {
49                 case font_size_small:
50                         brief_size = 16;
51                         status_size = 18;
52                         table_size = 11;
53                         break;
54                 default:
55                 case font_size_medium:
56                         brief_size = 22;
57                         status_size = 24;
58                         table_size = 14;
59                         break;
60                 case font_size_large:
61                         brief_size = 26;
62                         status_size = 30;
63                         table_size = 17;
64                         break;
65                 }
66                 label_font = new Font("Dialog", Font.PLAIN, brief_size);
67                 value_font = new Font("Monospaced", Font.PLAIN, brief_size);
68                 status_font = new Font("SansSerif", Font.BOLD, status_size);
69                 table_label_font = new Font("SansSerif", Font.PLAIN, table_size);
70                 table_value_font = new Font("Monospaced", Font.PLAIN, table_size);
71         }
72
73         static final int text_width = 20;
74
75         static public int state(String state) {
76                 if (!map_initialized)
77                         initialize_map();
78                 if (string_to_state.containsKey(state))
79                         return string_to_state.get(state);
80                 return ao_flight_invalid;
81         }
82
83         static public String state_name(int state) {
84                 if (state < 0 || state_to_string.length <= state)
85                         return "invalid";
86                 return state_to_string[state];
87         }
88
89         static final int AO_GPS_VALID = (1 << 4);
90         static final int AO_GPS_RUNNING = (1 << 5);
91         static final int AO_GPS_DATE_VALID = (1 << 6);
92         static final int AO_GPS_NUM_SAT_SHIFT = 0;
93         static final int AO_GPS_NUM_SAT_MASK = 0xf;
94
95         static final int AO_LOG_FORMAT_UNKNOWN = 0;
96         static final int AO_LOG_FORMAT_FULL = 1;
97         static final int AO_LOG_FORMAT_TINY = 2;
98         static final int AO_LOG_FORMAT_TELEMETRY = 3;
99         static final int AO_LOG_FORMAT_TELESCIENCE = 4;
100         static final int AO_LOG_FORMAT_MEGAMETRUM = 5;
101         static final int AO_LOG_FORMAT_NONE = 127;
102
103         static boolean isspace(int c) {
104                 switch (c) {
105                 case ' ':
106                 case '\t':
107                         return true;
108                 }
109                 return false;
110         }
111
112         static boolean ishex(int c) {
113                 if ('0' <= c && c <= '9')
114                         return true;
115                 if ('a' <= c && c <= 'f')
116                         return true;
117                 if ('A' <= c && c <= 'F')
118                         return true;
119                 return false;
120         }
121
122         static boolean ishex(String s) {
123                 for (int i = 0; i < s.length(); i++)
124                         if (!ishex(s.charAt(i)))
125                                 return false;
126                 return true;
127         }
128
129         static int fromhex(int c) {
130                 if ('0' <= c && c <= '9')
131                         return c - '0';
132                 if ('a' <= c && c <= 'f')
133                         return c - 'a' + 10;
134                 if ('A' <= c && c <= 'F')
135                         return c - 'A' + 10;
136                 return -1;
137         }
138
139         static int fromhex(String s) throws NumberFormatException {
140                 int c, v = 0;
141                 for (int i = 0; i < s.length(); i++) {
142                         c = s.charAt(i);
143                         if (!ishex(c)) {
144                                 if (i == 0)
145                                         throw new NumberFormatException(String.format("invalid hex \"%s\"", s));
146                                 return v;
147                         }
148                         v = v * 16 + fromhex(c);
149                 }
150                 return v;
151         }
152
153         static boolean isdec(int c) {
154                 if ('0' <= c && c <= '9')
155                         return true;
156                 return false;
157         }
158
159         static boolean isdec(String s) {
160                 for (int i = 0; i < s.length(); i++)
161                         if (!isdec(s.charAt(i)))
162                                 return false;
163                 return true;
164         }
165
166         static int fromdec(int c) {
167                 if ('0' <= c && c <= '9')
168                         return c - '0';
169                 return -1;
170         }
171
172         static int int8(int[] bytes, int i) {
173                 return (int) (byte) bytes[i];
174         }
175
176         static int uint8(int[] bytes, int i) {
177                 return bytes[i];
178         }
179
180         static int int16(int[] bytes, int i) {
181                 return (int) (short) (bytes[i] + (bytes[i+1] << 8));
182         }
183
184         static int uint16(int[] bytes, int i) {
185                 return bytes[i] + (bytes[i+1] << 8);
186         }
187
188         static int uint32(int[] bytes, int i) {
189                 return bytes[i] +
190                         (bytes[i+1] << 8) +
191                         (bytes[i+2] << 16) +
192                         (bytes[i+3] << 24);
193         }
194
195         static final Charset    unicode_set = Charset.forName("UTF-8");
196
197         static String string(int[] bytes, int s, int l) {
198                 if (s + l > bytes.length) {
199                         if (s > bytes.length) {
200                                 s = bytes.length;
201                                 l = 0;
202                         } else {
203                                 l = bytes.length - s;
204                         }
205                 }
206
207                 int i;
208                 for (i = l - 1; i >= 0; i--)
209                         if (bytes[s+i] != 0)
210                                 break;
211
212                 l = i + 1;
213                 byte[]  b = new byte[l];
214
215                 for (i = 0; i < l; i++)
216                         b[i] = (byte) bytes[s+i];
217                 String n = new String(b, unicode_set);
218                 return n;
219         }
220
221         static int hexbyte(String s, int i) {
222                 int c0, c1;
223
224                 if (s.length() < i + 2)
225                         throw new NumberFormatException(String.format("invalid hex \"%s\"", s));
226                 c0 = s.charAt(i);
227                 if (!Altos.ishex(c0))
228                         throw new NumberFormatException(String.format("invalid hex \"%c\"", c0));
229                 c1 = s.charAt(i+1);
230                 if (!Altos.ishex(c1))
231                         throw new NumberFormatException(String.format("invalid hex \"%c\"", c1));
232                 return Altos.fromhex(c0) * 16 + Altos.fromhex(c1);
233         }
234
235         static int[] hexbytes(String s) {
236                 int     n;
237                 int[]   r;
238                 int     i;
239
240                 if ((s.length() & 1) != 0)
241                         throw new NumberFormatException(String.format("invalid line \"%s\"", s));
242                 n = s.length() / 2;
243                 r = new int[n];
244                 for (i = 0; i < n; i++)
245                         r[i] = Altos.hexbyte(s, i * 2);
246                 return r;
247         }
248
249         static int fromdec(String s) throws NumberFormatException {
250                 int c, v = 0;
251                 int sign = 1;
252                 for (int i = 0; i < s.length(); i++) {
253                         c = s.charAt(i);
254                         if (i == 0 && c == '-') {
255                                 sign = -1;
256                         } else if (!isdec(c)) {
257                                 if (i == 0)
258                                         throw new NumberFormatException(String.format("invalid number \"%s\"", s));
259                                 return v;
260                         } else
261                                 v = v * 10 + fromdec(c);
262                 }
263                 return v * sign;
264         }
265
266         static String replace_extension(String input, String extension) {
267                 int dot = input.lastIndexOf(".");
268                 if (dot > 0)
269                         input = input.substring(0,dot);
270                 return input.concat(extension);
271         }
272
273         static public boolean initialized = false;
274         static public boolean loaded_library = false;
275
276         public static boolean load_library() {
277                 if (!initialized) {
278                         try {
279                                 System.loadLibrary("altos");
280                                 libaltos.altos_init();
281                                 loaded_library = true;
282                         } catch (UnsatisfiedLinkError e) {
283                                 try {
284                                         System.loadLibrary("altos64");
285                                         libaltos.altos_init();
286                                         loaded_library = true;
287                                 } catch (UnsatisfiedLinkError e2) {
288                                         loaded_library = false;
289                                 }
290                         }
291                         initialized = true;
292                 }
293                 return loaded_library;
294         }
295
296         static int usb_vendor_altusmetrum() {
297                 load_library();
298                 return 0xfffe;
299         }
300
301         static int usb_product_altusmetrum() {
302                 load_library();
303                 return 0x000a;
304         }
305
306         static int usb_product_altusmetrum_min() {
307                 load_library();
308                 return 0x000a;
309         }
310
311         static int usb_product_altusmetrum_max() {
312                 load_library();
313                 return 0x0013;
314         }
315
316         static int usb_product_telemetrum() {
317                 load_library();
318                 return 0x000b;
319         }
320
321         static int usb_product_teledongle() {
322                 load_library();
323                 return 0x000c;
324         }
325
326         static int usb_product_teleterra() {
327                 load_library();
328                 return 0x000d;
329         }
330
331         static int usb_product_telebt() {
332                 load_library();
333                 return 0x000e;
334         }
335
336         static int usb_product_telelaunch() {
337                 load_library();
338                 return 0x000f;
339         }
340
341         static int usb_product_telelco() {
342                 load_library();
343                 return 0x0010;
344         }
345
346         static int usb_product_telescience() {
347                 load_library();
348                 return 0x0011;
349         }
350
351         static int usb_product_telepyro() {
352                 load_library();
353                 return 0x0012;
354         }
355
356         public final static int vendor_altusmetrum = usb_vendor_altusmetrum();
357         public final static int product_altusmetrum = usb_product_altusmetrum();
358         public final static int product_telemetrum = usb_product_telemetrum();
359         public final static int product_teledongle = usb_product_teledongle();
360         public final static int product_teleterra = usb_product_teleterra();
361         public final static int product_telebt = usb_product_telebt();
362         public final static int product_telelaunch = usb_product_telelaunch();
363         public final static int product_tele10 = usb_product_telelco();
364         public final static int product_telescience = usb_product_telescience();
365         public final static int product_telepyro = usb_product_telepyro();
366         public final static int product_altusmetrum_min = usb_product_altusmetrum_min();
367         public final static int product_altusmetrum_max = usb_product_altusmetrum_max();
368
369         public final static int product_any = 0x10000;
370         public final static int product_basestation = 0x10000 + 1;
371
372         static String bt_product_telebt() {
373                 load_library();
374                 return "TeleBT";
375         }
376
377         public final static String bt_product_telebt = bt_product_telebt();
378
379         public static AltosBTKnown bt_known = new AltosBTKnown();
380 }