altosui: Use persistent list of bluetooth devices for device dialogs
authorKeith Packard <keithp@keithp.com>
Tue, 19 Apr 2011 15:43:40 +0000 (08:43 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 19 Apr 2011 15:43:40 +0000 (08:43 -0700)
Store a list of known bluetooth devices as preferences. Always include
those in device dialogs with an option to go browse for more devices
in both the device dialog and the Configure AltosUI dialog.

Signed-off-by: Keith Packard <keithp@keithp.com>
16 files changed:
altosui/Altos.java
altosui/AltosBTDevice.java
altosui/AltosBTDeviceIterator.java
altosui/AltosBTKnown.java [new file with mode: 0644]
altosui/AltosBTManage.java
altosui/AltosConfigureUI.java
altosui/AltosDeviceDialog.java
altosui/AltosFlightUI.java
altosui/AltosPreferences.java
altosui/AltosSiteMap.java
altosui/AltosUI.java
altosui/AltosUSBDevice.java
altosui/Makefile.am
altosui/libaltos/cjnitest.c
altosui/libaltos/libaltos.c
altosui/libaltos/libaltos.h

index d221077e290d542596354313e98cfdaa099a34dd..a087f73a2f662c6aa738e7008bb79e0d937a7972 100644 (file)
@@ -309,4 +309,6 @@ public class Altos {
        }
 
        public final static String bt_product_telebt = bt_product_telebt();
+
+       public static AltosBTKnown bt_known = new AltosBTKnown();
 }
index ff2be49a66279009c6fc0f32ea69dce4d6ad89b7..c2721b262c0df0b83a0a23a9a20900e961d3d80a 100644 (file)
@@ -86,8 +86,9 @@ public class AltosBTDevice extends altos_bt_device implements AltosDevice {
 
        public boolean matchProduct(int want_product) {
 
-               if (!isAltusMetrum())
-                       return false;
+               System.out.printf("matchProduct %s %d\n", toString(), want_product);
+//             if (!isAltusMetrum())
+//                     return false;
 
                if (want_product == Altos.product_any)
                        return true;
@@ -100,4 +101,23 @@ public class AltosBTDevice extends altos_bt_device implements AltosDevice {
 
                return false;
        }
+
+       public boolean equals(Object o) {
+               if (!(o instanceof AltosBTDevice))
+                       return false;
+               AltosBTDevice other = (AltosBTDevice) o;
+               System.out.printf("AltosBTDevice equals %s == %s\n", toString(), other.toString());
+               return getName().equals(other.getName()) && getAddr().equals(other.getAddr());
+       }
+
+       public int hashCode() {
+               return getName().hashCode() ^ getAddr().hashCode();
+       }
+
+       public AltosBTDevice(String name, String addr) {
+               libaltos.altos_bt_fill_in(name, addr,this);
+       }
+
+       public AltosBTDevice() {
+       }
 }
\ No newline at end of file
index 63ce3674f8673f10a21136d9b5719dc4c693790e..7c360705d3cdd4c2e58e5d68312293934124c34a 100644 (file)
@@ -21,7 +21,6 @@ import java.util.*;
 import libaltosJNI.*;
 
 public class AltosBTDeviceIterator implements Iterator<AltosBTDevice> {
-       int             product;
        AltosBTDevice   current;
        boolean         done;
        SWIGTYPE_p_altos_bt_list list;
@@ -58,11 +57,9 @@ public class AltosBTDeviceIterator implements Iterator<AltosBTDevice> {
                throw new UnsupportedOperationException();
        }
 
-       public AltosBTDeviceIterator(int in_product) {
-               product = in_product;
+       public AltosBTDeviceIterator(int inquiry_time) {
                done = false;
                current = null;
-               list = libaltos.altos_bt_list_start();
-               System.out.printf("Iteration of BT list started\n");
+               list = libaltos.altos_bt_list_start(inquiry_time);
        }
 }
diff --git a/altosui/AltosBTKnown.java b/altosui/AltosBTKnown.java
new file mode 100644 (file)
index 0000000..9583063
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package altosui;
+import java.lang.*;
+import java.util.*;
+import libaltosJNI.*;
+import java.util.prefs.*;
+
+public class AltosBTKnown implements Iterable<AltosBTDevice> {
+       LinkedList<AltosBTDevice>       devices = new LinkedList<AltosBTDevice>();
+       Preferences                     bt_pref = AltosPreferences.bt_devices();
+
+       private String get_address(String name) {
+               return bt_pref.get(name, "");
+       }
+
+       private void set_address(String name, String addr) {
+               bt_pref.put(name, addr);
+               System.out.printf("saving known %s %s\n", name, addr);
+       }
+
+       private void remove(String name) {
+               bt_pref.remove(name);
+       }
+
+       private void load() {
+               try {
+                       String[] names = bt_pref.keys();
+                       for (int i = 0; i < names.length; i++) {
+                               String  name = names[i];
+                               String  addr = get_address(name);
+                               System.out.printf("Known device %s %s\n", name, addr);
+                               devices.add(new AltosBTDevice(name, addr));
+                       }
+               } catch (BackingStoreException be) {
+               } catch (IllegalStateException ie) {
+               }
+       }
+
+       public Iterator<AltosBTDevice> iterator() {
+               return devices.iterator();
+       }
+
+       private void flush() {
+               AltosPreferences.flush_preferences();
+       }
+
+       public void set(Iterable<AltosBTDevice> new_devices) {
+               for (AltosBTDevice old : devices) {
+                       boolean found = false;
+                       for (AltosBTDevice new_device : new_devices) {
+                               if (new_device.equals(old)) {
+                                       found = true;
+                                       break;
+                               }
+                       }
+                       if (!found)
+                               remove(old.getName());
+               }
+               devices = new LinkedList<AltosBTDevice>();
+               for (AltosBTDevice new_device : new_devices) {
+                       devices.add(new_device);
+                       set_address(new_device.getName(), new_device.getAddr());
+               }
+               flush();
+       }
+
+       public List<AltosDevice> list(int product) {
+               LinkedList<AltosDevice> list = new LinkedList<AltosDevice>();
+               for (AltosBTDevice device : devices) {
+                       if (device.matchProduct(product))
+                               list.add(device);
+               }
+               return list;
+       }
+
+       public AltosBTKnown() {
+               devices = new LinkedList<AltosBTDevice>();
+               bt_pref = AltosPreferences.bt_devices();
+               load();
+       }
+}
\ No newline at end of file
index 66e1210e9eb37aa627fa59bec85a6a68f4ecf1b1..98a8b757f326d34325d5e7968e138545291b48ee 100644 (file)
@@ -22,6 +22,8 @@ import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.filechooser.FileNameExtensionFilter;
 import javax.swing.table.*;
+import javax.swing.event.*;
+import javax.swing.plaf.basic.*;
 import java.io.*;
 import java.util.*;
 import java.text.*;
@@ -30,17 +32,32 @@ import java.util.concurrent.*;
 
 import libaltosJNI.*;
 
-public class AltosBTManage extends JDialog implements ActionListener {
+public class AltosBTManage extends JDialog implements ActionListener, Iterable<AltosBTDevice> {
        LinkedBlockingQueue<AltosBTDevice> found_devices;
        Frame frame;
+       LinkedList<ActionListener> listeners;
+       AltosBTKnown    bt_known;
 
        class DeviceList extends JList implements Iterable<AltosBTDevice> {
                LinkedList<AltosBTDevice> devices;
                DefaultListModel        list_model;
 
                public void add (AltosBTDevice device) {
-                       devices.add(device);
-                       list_model.addElement(device);
+                       if (!devices.contains(device)) {
+                               devices.add(device);
+                               list_model.addElement(device);
+                       }
+               }
+
+               public void remove (AltosBTDevice device) {
+                       if (devices.contains(device)) {
+                               devices.remove(device);
+                               list_model.removeElement(device);
+                       }
+               }
+
+               public boolean contains(AltosBTDevice device) {
+                       return devices.contains(device);
                }
 
                //Subclass JList to workaround bug 4832765, which can cause the
@@ -75,6 +92,14 @@ public class AltosBTManage extends JDialog implements ActionListener {
                        return devices.iterator();
                }
 
+               public java.util.List<AltosBTDevice> selected_list() {
+                       java.util.LinkedList<AltosBTDevice> l = new java.util.LinkedList<AltosBTDevice>();
+                       Object[] a = getSelectedValues();
+                       for (int i = 0; i < a.length; i++)
+                               l.add((AltosBTDevice)a[i]);
+                       return l;
+               }
+
                public DeviceList() {
                        devices = new LinkedList<AltosBTDevice>();
                        list_model = new DefaultListModel();
@@ -87,111 +112,233 @@ public class AltosBTManage extends JDialog implements ActionListener {
 
        DeviceList      visible_devices;
 
-       DeviceList      selected_devices;
+       DeviceList      known_devices;
+       Thread          bt_thread;
+
+       public Iterator<AltosBTDevice> iterator() {
+               return known_devices.iterator();
+       }
+
+       public void commit() {
+               bt_known.set(this);
+       }
+
+       public void add_known() {
+               for (AltosBTDevice device : visible_devices.selected_list()) {
+                       System.out.printf("Add known %s\n", device.toString());
+                       known_devices.add(device);
+                       visible_devices.remove(device);
+               }
+       }
+
+       public void remove_known() {
+               for (AltosBTDevice device : known_devices.selected_list()) {
+                       System.out.printf("Remove known %s\n", device.toString());
+                       known_devices.remove(device);
+                       visible_devices.add(device);
+               }
+       }
+
+       public void addActionListener(ActionListener l) {
+               listeners.add(l);
+       }
+
+       private void forwardAction(ActionEvent e) {
+               for (ActionListener l : listeners)
+                       l.actionPerformed(e);
+       }
 
        public void actionPerformed(ActionEvent e) {
+               String  command = e.getActionCommand();
+               System.out.printf("manage command %s\n", command);
+               if ("ok".equals(command)) {
+                       bt_thread.interrupt();
+                       commit();
+                       setVisible(false);
+                       forwardAction(e);
+               } else if ("cancel".equals(command)) {
+                       bt_thread.interrupt();
+                       setVisible(false);
+                       forwardAction(e);
+               } else if ("select".equals(command)) {
+                       add_known();
+               } else if ("deselect".equals(command)) {
+                       remove_known();
+               }
        }
 
        public void got_visible_device() {
                while (!found_devices.isEmpty()) {
                        AltosBTDevice   device = found_devices.remove();
-                       visible_devices.add(device);
+                       if (!known_devices.contains(device))
+                               visible_devices.add(device);
                }
        }
 
        class BTGetVisibleDevices implements Runnable {
                public void run () {
-
-                       try {
-                               AltosBTDeviceIterator   i = new AltosBTDeviceIterator(Altos.product_any);
-                               AltosBTDevice           device;
-
-                               while ((device = i.next()) != null) {
-                                       Runnable r;
-
-                                       found_devices.add(device);
-                                       r = new Runnable() {
-                                                       public void run() {
-                                                               got_visible_device();
-                                                       }
-                                               };
-                                       SwingUtilities.invokeLater(r);
+                       for (;;)
+                               for (int time = 1; time <= 8; time <<= 1) {
+                                       AltosBTDeviceIterator   i = new AltosBTDeviceIterator(time);
+                                       AltosBTDevice           device;
+
+                                       if (Thread.interrupted())
+                                               return;
+                                       try {
+                                               while ((device = i.next()) != null) {
+                                                       Runnable r;
+
+                                                       if (Thread.interrupted())
+                                                               return;
+                                                       found_devices.add(device);
+                                                       r = new Runnable() {
+                                                                       public void run() {
+                                                                               got_visible_device();
+                                                                       }
+                                                               };
+                                                       SwingUtilities.invokeLater(r);
+                                               }
+                                       } catch (Exception e) {
+                                               System.out.printf("uh-oh, exception %s\n", e.toString());
+                                       }
                                }
-                       } catch (Exception e) {
-                               System.out.printf("uh-oh, exception %s\n", e.toString());
-                       }
                }
        }
 
-       public static void show(Component frameComp) {
+       public static void show(Component frameComp, AltosBTKnown known) {
                Frame   frame = JOptionPane.getFrameForComponent(frameComp);
                AltosBTManage   dialog;
 
-               dialog = new AltosBTManage(frame);
+               dialog = new AltosBTManage(frame, known);
                dialog.setVisible(true);
        }
 
-       public AltosBTManage(Frame in_frame) {
+       public AltosBTManage(Frame in_frame, AltosBTKnown in_known) {
                super(in_frame, "Manage Bluetooth Devices", true);
 
                frame = in_frame;
-
+               bt_known = in_known;
                BTGetVisibleDevices     get_visible_devices = new BTGetVisibleDevices();
+               bt_thread = new Thread(get_visible_devices);
+               bt_thread.start();
 
-               Thread t = new Thread(get_visible_devices);
-               t.start();
+               listeners = new LinkedList<ActionListener>();
 
                found_devices = new LinkedBlockingQueue<AltosBTDevice>();
 
-               JButton cancelButton = new JButton("Cancel");
-               cancelButton.addActionListener(this);
-
-               final JButton selectButton = new JButton("Select");
-               selectButton.setActionCommand("select");
-               selectButton.addActionListener(this);
-               getRootPane().setDefaultButton(selectButton);
-
-               selected_devices = new DeviceList();
-               JScrollPane selected_list_scroller = new JScrollPane(selected_devices);
-               selected_list_scroller.setPreferredSize(new Dimension(400, 80));
-               selected_list_scroller.setAlignmentX(LEFT_ALIGNMENT);
+               Container pane = getContentPane();
+               pane.setLayout(new GridBagLayout());
+
+               GridBagConstraints c = new GridBagConstraints();
+               c.insets = new Insets(4,4,4,4);
+
+               /*
+                * Known devices label and list
+                */
+               c.fill = GridBagConstraints.NONE;
+               c.anchor = GridBagConstraints.WEST;
+               c.gridx = 0;
+               c.gridy = 0;
+               c.gridwidth = 1;
+               c.gridheight = 1;
+               pane.add(new JLabel("Known Devices"), c);
+
+               known_devices = new DeviceList();
+               for (AltosBTDevice device : bt_known)
+                       known_devices.add(device);
+
+               JScrollPane known_list_scroller = new JScrollPane(known_devices);
+               known_list_scroller.setPreferredSize(new Dimension(400, 80));
+               known_list_scroller.setAlignmentX(LEFT_ALIGNMENT);
+               c.fill = GridBagConstraints.BOTH;
+               c.anchor = GridBagConstraints.WEST;
+               c.gridx = 0;
+               c.gridy = 1;
+               c.gridwidth = 1;
+               c.gridheight = 2;
+               pane.add(known_list_scroller, c);
+
+               /*
+                * Visible devices label and list
+                */
+               c.fill = GridBagConstraints.NONE;
+               c.anchor = GridBagConstraints.WEST;
+               c.gridx = 2;
+               c.gridy = 0;
+               c.gridwidth = 1;
+               c.gridheight = 1;
+               pane.add(new JLabel("Visible Devices"), c);
 
                visible_devices = new DeviceList();
                JScrollPane visible_list_scroller = new JScrollPane(visible_devices);
                visible_list_scroller.setPreferredSize(new Dimension(400, 80));
                visible_list_scroller.setAlignmentX(LEFT_ALIGNMENT);
+               c.fill = GridBagConstraints.BOTH;
+               c.anchor = GridBagConstraints.WEST;
+               c.gridx = 2;
+               c.gridy = 1;
+               c.gridheight = 2;
+               c.gridwidth = 1;
+               pane.add(visible_list_scroller, c);
+
+               /*
+                * Arrows between the two lists
+                */
+               BasicArrowButton select_arrow = new BasicArrowButton(SwingConstants.WEST);
+               select_arrow.setActionCommand("select");
+               select_arrow.addActionListener(this);
+               c.fill = GridBagConstraints.NONE;
+               c.anchor = GridBagConstraints.SOUTH;
+               c.gridx = 1;
+               c.gridy = 1;
+               c.gridheight = 1;
+               c.gridwidth = 1;
+               pane.add(select_arrow, c);
+
+               BasicArrowButton deselect_arrow = new BasicArrowButton(SwingConstants.EAST);
+               deselect_arrow.setActionCommand("deselect");
+               deselect_arrow.addActionListener(this);
+               c.fill = GridBagConstraints.NONE;
+               c.anchor = GridBagConstraints.NORTH;
+               c.gridx = 1;
+               c.gridy = 2;
+               c.gridheight = 1;
+               c.gridwidth = 1;
+               pane.add(deselect_arrow, c);
+
+               JButton cancel_button = new JButton("Cancel");
+               cancel_button.setActionCommand("cancel");
+               cancel_button.addActionListener(this);
+               c.fill = GridBagConstraints.NONE;
+               c.anchor = GridBagConstraints.CENTER;
+               c.gridx = 0;
+               c.gridy = 3;
+               c.gridheight = 1;
+               c.gridwidth = 1;
+               pane.add(cancel_button, c);
+
+               JButton ok_button = new JButton("OK");
+               ok_button.setActionCommand("ok");
+               ok_button.addActionListener(this);
+               c.fill = GridBagConstraints.NONE;
+               c.anchor = GridBagConstraints.CENTER;
+               c.gridx = 2;
+               c.gridy = 3;
+               c.gridheight = 1;
+               c.gridwidth = 1;
+               pane.add(ok_button, c);
+
+               getRootPane().setDefaultButton(ok_button);
 
-               //Create a container so that we can add a title around
-               //the scroll pane.  Can't add a title directly to the
-               //scroll pane because its background would be white.
-               //Lay out the label and scroll pane from top to bottom.
-               JPanel listPane = new JPanel();
-               listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
-
-               JLabel label = new JLabel("Select Device");
-               label.setLabelFor(selected_devices);
-               listPane.add(label);
-               listPane.add(Box.createRigidArea(new Dimension(0,5)));
-               listPane.add(selected_list_scroller);
-               listPane.add(visible_list_scroller);
-               listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
-
-               //Lay out the buttons from left to right.
-               JPanel buttonPane = new JPanel();
-               buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
-               buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
-               buttonPane.add(Box.createHorizontalGlue());
-               buttonPane.add(cancelButton);
-               buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
-               buttonPane.add(selectButton);
-
-               //Put everything together, using the content pane's BorderLayout.
-               Container contentPane = getContentPane();
-               contentPane.add(listPane, BorderLayout.CENTER);
-               contentPane.add(buttonPane, BorderLayout.PAGE_END);
-
-               //Initialize values.
-//             list.setSelectedValue(initial, true);
                pack();
+               setLocationRelativeTo(frame);
+               setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+               addWindowListener(new WindowAdapter() {
+                       @Override
+                       public void windowClosing(WindowEvent e) {
+                               bt_thread.interrupt();
+                               setVisible(false);
+                       }
+               });
        }
 }
index a2755a06d818d12afcf22ac1744463da5e57ef17..0f5e4a3bd3a7335fdcc1fc8da9e54b8c7beb2de0 100644 (file)
@@ -204,7 +204,7 @@ public class AltosConfigureUI
                manage_bluetooth = new JButton("Manage Bluetooth");
                manage_bluetooth.addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent e) {
-                                       new AltosBTManage(AltosBTDevice.bt_product_any, owner);
+                                       AltosBTManage.show(owner, Altos.bt_known);
                                }
                        });
                c.gridx = 1;
index fa20f867524758cf51506067b536a4fb80dc2e54..e17504e2475580c4c75364ab060391cc1357a425 100644 (file)
@@ -26,37 +26,46 @@ import libaltosJNI.*;
 
 public class AltosDeviceDialog extends JDialog implements ActionListener {
 
-       public static AltosDevice show (Component frameComp, int product) {
-
-               Frame frame = JOptionPane.getFrameForComponent(frameComp);
-               AltosDevice[]   devices;
-               devices = AltosUSBDevice.list(product);
-               AltosDeviceDialog       dialog;
-
-               dialog = new AltosDeviceDialog(frame, frameComp,
-                                              devices);
-               dialog.setVisible(true);
-               return dialog.getValue();
-       }
-
        private AltosDevice     value;
        private JList           list;
        private JButton         cancel_button;
        private JButton         select_button;
        private JButton         manage_bluetooth_button;
        private Frame           frame;
+       private int             product;
 
        private AltosDevice getValue() {
                return value;
        }
 
-       private AltosDeviceDialog (Frame in_frame, Component location,
-                                  AltosDevice[] devices) {
+       private AltosDevice[] devices() {
+               java.util.List<AltosDevice>     usb_devices = AltosUSBDevice.list(product);
+               java.util.List<AltosDevice>     bt_devices = Altos.bt_known.list(product);
+               AltosDevice[]                   devices = new AltosDevice[usb_devices.size() + bt_devices.size()];
+
+               for (int i = 0; i < usb_devices.size(); i++)
+                       devices[i] = usb_devices.get(i);
+               int off = usb_devices.size();
+               for (int j = 0; j < bt_devices.size(); j++)
+                       devices[off + j] = bt_devices.get(j);
+               return devices;
+       }
+
+       private void update_devices() {
+               AltosDevice[] devices = devices();
+               list.setListData(devices);
+               select_button.setEnabled(devices.length > 0);
+       }
+
+       private AltosDeviceDialog (Frame in_frame, Component location, int in_product) {
                super(in_frame, "Device Selection", true);
 
+               product = in_product;
                frame = in_frame;
                value = null;
 
+               AltosDevice[]   devices = devices();
+
                cancel_button = new JButton("Cancel");
                cancel_button.setActionCommand("cancel");
                cancel_button.addActionListener(this);
@@ -147,7 +156,7 @@ public class AltosDeviceDialog extends JDialog implements ActionListener {
                contentPane.add(buttonPane, BorderLayout.PAGE_END);
 
                //Initialize values.
-               if (devices != null && devices.length > 0)
+               if (devices != null && devices.length != 0)
                        list.setSelectedValue(devices[0], true);
                pack();
                setLocationRelativeTo(location);
@@ -158,10 +167,20 @@ public class AltosDeviceDialog extends JDialog implements ActionListener {
                if ("select".equals(e.getActionCommand()))
                        value = (AltosDevice)(list.getSelectedValue());
                if ("manage".equals(e.getActionCommand())) {
-                       AltosBTManage.show(frame);
+                       AltosBTManage.show(frame, Altos.bt_known);
+                       update_devices();
                        return;
                }
                setVisible(false);
        }
 
+       public static AltosDevice show (Component frameComp, int product) {
+
+               Frame                           frame = JOptionPane.getFrameForComponent(frameComp);
+               AltosDeviceDialog       dialog;
+
+               dialog = new AltosDeviceDialog(frame, frameComp, product);
+               dialog.setVisible(true);
+               return dialog.getValue();
+       }
 }
index 66dcdad57863f8942a49d2fc3d87ea3834ab5d48..eb6c6d9d82d1edc5f3500dcc142f3769dfc6d39d 100644 (file)
@@ -122,7 +122,7 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {
        JComboBox       telemetries;
 
        public AltosFlightUI(AltosVoice in_voice, AltosFlightReader in_reader, final int serial) {
-               AltosPreferences.init(this);
+               AltosPreferences.set_component(this);
 
                voice = in_voice;
                reader = in_reader;
index 5f82765569dae85f0a69211c41bc0d1ed04b119f..b1192be110e1f3573e2626939f73e238c68a3fda 100644 (file)
@@ -79,11 +79,9 @@ class AltosPreferences {
        /* Serial debug */
        static boolean serial_debug;
 
-       public static void init(Component ui) {
+       public static void init() {
                preferences = Preferences.userRoot().node("/org/altusmetrum/altosui");
 
-               component = ui;
-
                /* Initialize logdir from preferences */
                String logdir_string = preferences.get(logdirPreference, null);
                if (logdir_string != null)
@@ -116,14 +114,23 @@ class AltosPreferences {
                AltosSerial.set_debug(serial_debug);
        }
 
+       static { init(); }
+
+       static void set_component(Component in_component) {
+               component = in_component;
+       }
+
        static void flush_preferences() {
                try {
                        preferences.flush();
                } catch (BackingStoreException ee) {
-                       JOptionPane.showMessageDialog(component,
-                                                     preferences.absolutePath(),
-                                                     "Cannot save prefernces",
-                                                     JOptionPane.ERROR_MESSAGE);
+                       if (component != null)
+                               JOptionPane.showMessageDialog(component,
+                                                             preferences.absolutePath(),
+                                                             "Cannot save prefernces",
+                                                             JOptionPane.ERROR_MESSAGE);
+                       else
+                               System.err.printf("Cannot save preferences\n");
                }
        }
 
@@ -262,4 +269,8 @@ class AltosPreferences {
        public static boolean serial_debug() {
                return serial_debug;
        }
+
+       public static Preferences bt_devices() {
+               return preferences.node("bt_devices");
+       }
 }
index f4b6b7e0a52350bf3c66d32d92807ecb61535931..7575c10e62d3b95cfa23ca2c7d938485573d79af 100644 (file)
@@ -164,8 +164,6 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
        }
 
        public static void prefetchMaps(double lat, double lng, int w, int h) {
-               AltosPreferences.init(null);
-
                AltosSiteMap asm = new AltosSiteMap(true);
                asm.centre = asm.getBaseLocation(lat, lng);
 
index 4b808c410d35912cdf896997847209168310e1df..7955c1c20660a5348537a9a5450cdacf5b7434b0 100644 (file)
@@ -99,7 +99,7 @@ public class AltosUI extends JFrame {
                if (imgURL != null)
                        setIconImage(new ImageIcon(imgURL).getImage());
 
-               AltosPreferences.init(this);
+               AltosPreferences.set_component(this);
 
                pane = getContentPane();
                gridbag = new GridBagLayout();
@@ -397,9 +397,9 @@ public class AltosUI extends JFrame {
                        AltosUI altosui = new AltosUI();
                        altosui.setVisible(true);
 
-                       AltosDevice[] devices = AltosUSBDevice.list(Altos.product_basestation);
-                       for (int i = 0; i < devices.length; i++)
-                               altosui.telemetry_window(devices[i]);
+                       java.util.List<AltosDevice> devices = AltosUSBDevice.list(Altos.product_basestation);
+                       for (AltosDevice device : devices)
+                               altosui.telemetry_window(device);
                }
        }
 }
index deed00568b1d023fe3ad50e332c6a83d45598e1b..dc746a64fb4aa7de038872bbf18f5fde13d7d523 100644 (file)
@@ -77,13 +77,13 @@ public class AltosUSBDevice  extends altos_device implements AltosDevice {
                return false;
        }
 
-       static AltosUSBDevice[] list(int product) {
+       static java.util.List<AltosDevice> list(int product) {
                if (!Altos.load_library())
                        return null;
 
                SWIGTYPE_p_altos_list list = libaltos.altos_list_start();
 
-               ArrayList<AltosUSBDevice> device_list = new ArrayList<AltosUSBDevice>();
+               ArrayList<AltosDevice> device_list = new ArrayList<AltosDevice>();
                if (list != null) {
                        for (;;) {
                                AltosUSBDevice device = new AltosUSBDevice();
@@ -95,9 +95,6 @@ public class AltosUSBDevice  extends altos_device implements AltosDevice {
                        libaltos.altos_list_finish(list);
                }
 
-               AltosUSBDevice[] devices = new AltosUSBDevice[device_list.size()];
-               for (int i = 0; i < device_list.size(); i++)
-                       devices[i] = device_list.get(i);
-               return devices;
+               return device_list;
        }
 }
\ No newline at end of file
index f2de4a3a437cba30c5075fbaa7b6f1a0fc2c36ae..f4d84ad29648ee93fa98b030614106049ffa51aa 100644 (file)
@@ -30,6 +30,7 @@ altosui_JAVA = \
        AltosBTDevice.java \
        AltosBTDeviceIterator.java \
        AltosBTManage.java \
+       AltosBTKnown.java \
        AltosDisplayThread.java \
        AltosEepromChunk.java \
        AltosEepromDelete.java \
index 795616436aa99a7da70c9463b3e431aab7ba0c96..88e40d739bc0e469af9e3680186df4ce846a6118 100644 (file)
@@ -41,7 +41,7 @@ main ()
                altos_close(file);
        }
        altos_list_finish(list);
-       bt_list = altos_bt_list_start();
+       bt_list = altos_bt_list_start(8);
        while (altos_bt_list_next(bt_list, &bt_device)) {
                printf ("%s %s\n", bt_device.name, bt_device.addr);
                if (strncmp(bt_device.name, "TeleBT", 6) == 0) {
index 13635a0da0f2d0b4311112c029926eddd6e91831..2c47f3e531f2b55d975a7a261193cafb17eb6a42 100644 (file)
@@ -591,10 +591,9 @@ struct altos_bt_list {
 };
 
 #define INQUIRY_MAX_RSP        255
-#define INQUIRY_LEN    8
 
 struct altos_bt_list *
-altos_bt_list_start(void)
+altos_bt_list_start(int inquiry_time)
 {
        struct altos_bt_list    *bt_list;
 
@@ -614,7 +613,7 @@ altos_bt_list_start(void)
                goto no_sock;
 
        bt_list->num_rsp = hci_inquiry(bt_list->dev_id,
-                                      INQUIRY_LEN,
+                                      inquiry_time,
                                       INQUIRY_MAX_RSP,
                                       NULL,
                                       &bt_list->ii,
@@ -665,6 +664,15 @@ altos_bt_list_finish(struct altos_bt_list *bt_list)
        free(bt_list);
 }
 
+void
+altos_bt_fill_in(char *name, char *addr, struct altos_bt_device *device)
+{
+       strncpy(device->name, name, sizeof (device->name));
+       device->name[sizeof(device->name)-1] = '\0';
+       strncpy(device->addr, addr, sizeof (device->addr));
+       device->addr[sizeof(device->addr)-1] = '\0';
+}
+
 struct altos_file *
 altos_bt_open(struct altos_bt_device *device)
 {
@@ -768,7 +776,7 @@ get_number(io_object_t object, CFStringRef entry, int *result)
 }
 
 struct altos_list *
-altos_list_start(void)
+altos_list_start(int time)
 {
        struct altos_list *list = calloc (sizeof (struct altos_list), 1);
        CFMutableDictionaryRef matching_dictionary = IOServiceMatching("IOUSBDevice");
index 9c3f965589d754b2a6ee784429c3e1c9c6a20d8f..f710919c510ade1ba1fb96c026c45b9f6cee15fb 100644 (file)
@@ -110,7 +110,7 @@ PUBLIC int
 altos_getchar(struct altos_file *file, int timeout);
 
 PUBLIC struct altos_bt_list *
-altos_bt_list_start(void);
+altos_bt_list_start(int inquiry_time);
 
 PUBLIC int
 altos_bt_list_next(struct altos_bt_list *list, struct altos_bt_device *device);
@@ -118,6 +118,9 @@ altos_bt_list_next(struct altos_bt_list *list, struct altos_bt_device *device);
 PUBLIC void
 altos_bt_list_finish(struct altos_bt_list *list);
 
+PUBLIC void
+altos_bt_fill_in(char *name, char *addr, struct altos_bt_device *device);
+
 PUBLIC struct altos_file *
 altos_bt_open(struct altos_bt_device *device);