diff options
Diffstat (limited to 'altosuilib')
| -rw-r--r-- | altosuilib/AltosBTDevice.java | 125 | ||||
| -rw-r--r-- | altosuilib/AltosBTDeviceIterator.java | 64 | ||||
| -rw-r--r-- | altosuilib/AltosBTKnown.java | 101 | ||||
| -rw-r--r-- | altosuilib/AltosBTManage.java | 353 | ||||
| -rw-r--r-- | altosuilib/AltosDeviceUIDialog.java | 69 | ||||
| -rw-r--r-- | altosuilib/AltosSerial.java | 208 | ||||
| -rw-r--r-- | altosuilib/AltosSerialInUseException.java | 26 | ||||
| -rw-r--r-- | altosuilib/Makefile.am | 10 |
8 files changed, 955 insertions, 1 deletions
diff --git a/altosuilib/AltosBTDevice.java b/altosuilib/AltosBTDevice.java new file mode 100644 index 00000000..beefa532 --- /dev/null +++ b/altosuilib/AltosBTDevice.java @@ -0,0 +1,125 @@ +/* + * 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 org.altusmetrum.altosuilib_2; + +import libaltosJNI.*; +import org.altusmetrum.altoslib_4.*; + +public class AltosBTDevice extends altos_bt_device implements AltosDevice { + + public String getProductName() { + String name = getName(); + if (name == null) + return "Altus Metrum"; + int dash = name.lastIndexOf("-"); + if (dash < 0) + return name; + return name.substring(0,dash); + } + + public int getProduct() { + if (AltosLib.bt_product_telebt.equals(getProductName())) + return AltosLib.product_telebt; + return 0; + } + + public String getPath() { + return getAddr(); + } + + public String getErrorString() { + altos_error error = new altos_error(); + + libaltos.altos_get_last_error(error); + return String.format("%s (%d)", error.getString(), error.getCode()); + } + + public int getSerial() { + String name = getName(); + if (name == null) + return 0; + int dash = name.lastIndexOf("-"); + if (dash < 0 || dash >= name.length()) + return 0; + String sn = name.substring(dash + 1, name.length()); + try { + return Integer.parseInt(sn); + } catch (NumberFormatException ne) { + return 0; + } + } + + public String toString() { + return String.format("%-20.20s %4d %s", + getProductName(), getSerial(), getAddr()); + } + + public String toShortString() { + return String.format("%s %d %s", + getProductName(), getSerial(), getAddr()); + + } + + public SWIGTYPE_p_altos_file open() { + return libaltos.altos_bt_open(this); + } + + /* + private boolean isAltusMetrum() { + if (getName().startsWith(Altos.bt_product_telebt)) + return true; + return false; + } + */ + + public boolean matchProduct(int want_product) { + +// if (!isAltusMetrum()) +// return false; + + if (want_product == AltosLib.product_any) + return true; + + if (want_product == AltosLib.product_basestation) + return matchProduct(AltosLib.product_telebt); + + if (want_product == getProduct()) + return true; + + return false; + } + + public boolean equals(Object o) { + if (!(o instanceof AltosBTDevice)) + return false; + AltosBTDevice other = (AltosBTDevice) o; + return getName().equals(other.getName()) && getAddr().equals(other.getAddr()); + } + + public int hashCode() { + return getName().hashCode() ^ getAddr().hashCode(); + } + + public AltosBTDevice(String name, String addr) { + AltosUILib.load_library(); + libaltos.altos_bt_fill_in(name, addr,this); + } + + public AltosBTDevice() { + } +} diff --git a/altosuilib/AltosBTDeviceIterator.java b/altosuilib/AltosBTDeviceIterator.java new file mode 100644 index 00000000..cad60ffb --- /dev/null +++ b/altosuilib/AltosBTDeviceIterator.java @@ -0,0 +1,64 @@ +/* + * 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 org.altusmetrum.altosuilib_2; + +import java.util.*; +import libaltosJNI.*; +import org.altusmetrum.altoslib_4.*; + +public class AltosBTDeviceIterator implements Iterator<AltosBTDevice> { + AltosBTDevice current; + boolean done; + SWIGTYPE_p_altos_bt_list list; + + public boolean hasNext() { + if (list == null) + return false; + if (current != null) + return true; + if (done) + return false; + current = new AltosBTDevice(); + while (libaltos.altos_bt_list_next(list, current) != 0) { +// if (current.matchProduct(product)) + return true; + } + current = null; + done = true; + return false; + } + + public AltosBTDevice next() { + if (hasNext()) { + AltosBTDevice next = current; + current = null; + return next; + } + return null; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public AltosBTDeviceIterator(int inquiry_time) { + done = false; + current = null; + list = libaltos.altos_bt_list_start(inquiry_time); + } +} diff --git a/altosuilib/AltosBTKnown.java b/altosuilib/AltosBTKnown.java new file mode 100644 index 00000000..02883c75 --- /dev/null +++ b/altosuilib/AltosBTKnown.java @@ -0,0 +1,101 @@ +/* + * 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 org.altusmetrum.altosuilib_2; + +import java.util.*; +import org.altusmetrum.altoslib_4.*; + +public class AltosBTKnown implements Iterable<AltosBTDevice> { + LinkedList<AltosBTDevice> devices = new LinkedList<AltosBTDevice>(); + AltosPreferencesBackend bt_pref = AltosUIPreferences.bt_devices(); + + private String get_address(String name) { + return bt_pref.getString(name, ""); + } + + private void set_address(String name, String addr) { + bt_pref.putString(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); + devices.add(new AltosBTDevice(name, addr)); + } + } catch (IllegalStateException ie) { + } + } + + public Iterator<AltosBTDevice> iterator() { + return devices.iterator(); + } + + private void flush() { + AltosUIPreferences.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 = AltosUIPreferences.bt_devices(); + load(); + } + + static AltosBTKnown known; + + static public AltosBTKnown bt_known() { + if (known == null) + known = new AltosBTKnown(); + return known; + } +} diff --git a/altosuilib/AltosBTManage.java b/altosuilib/AltosBTManage.java new file mode 100644 index 00000000..6da0a3eb --- /dev/null +++ b/altosuilib/AltosBTManage.java @@ -0,0 +1,353 @@ +/* + * 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 org.altusmetrum.altosuilib_2; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.plaf.basic.*; +import java.util.*; +import java.util.concurrent.*; +import org.altusmetrum.altoslib_4.*; + +public class AltosBTManage extends AltosUIDialog implements ActionListener, Iterable<AltosBTDevice> { + LinkedBlockingQueue<AltosBTDevice> found_devices; + Frame frame; + LinkedList<ActionListener> listeners; + AltosBTKnown bt_known; + + class DeviceList extends JList<AltosBTDevice> implements Iterable<AltosBTDevice> { + LinkedList<AltosBTDevice> devices; + DefaultListModel<AltosBTDevice> list_model; + + public void add (AltosBTDevice 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 + //scroll pane to not let the user easily scroll up to the beginning + //of the list. An alternative would be to set the unitIncrement + //of the JScrollBar to a fixed value. You wouldn't get the nice + //aligned scrolling, but it should work. + public int getScrollableUnitIncrement(Rectangle visibleRect, + int orientation, + int direction) { + int row; + if (orientation == SwingConstants.VERTICAL && + direction < 0 && (row = getFirstVisibleIndex()) != -1) { + Rectangle r = getCellBounds(row, row); + if ((r.y == visibleRect.y) && (row != 0)) { + Point loc = r.getLocation(); + loc.y--; + int prevIndex = locationToIndex(loc); + Rectangle prevR = getCellBounds(prevIndex, prevIndex); + + if (prevR == null || prevR.y >= r.y) { + return 0; + } + return prevR.height; + } + } + return super.getScrollableUnitIncrement( + visibleRect, orientation, direction); + } + + public Iterator<AltosBTDevice> iterator() { + return devices.iterator(); + } + + public java.util.List<AltosBTDevice> selected_list() throws InterruptedException { + return getSelectedValuesList(); + } + + public DeviceList() { + devices = new LinkedList<AltosBTDevice>(); + list_model = new DefaultListModel<AltosBTDevice>(); + setModel(list_model); + setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + setLayoutOrientation(JList.HORIZONTAL_WRAP); + setVisibleRowCount(-1); + } + } + + DeviceList visible_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() { + try { + for (AltosBTDevice device : visible_devices.selected_list()) { + known_devices.add(device); + visible_devices.remove(device); + } + } catch (InterruptedException ie) { + } + } + + public void remove_known() { + try { + for (AltosBTDevice device : known_devices.selected_list()) { + known_devices.remove(device); + visible_devices.add(device); + } + } catch (InterruptedException ie) { + } + } + + 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(); + 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(); + if (!known_devices.contains(device)) + visible_devices.add(device); + } + } + + class BTGetVisibleDevices implements Runnable { + public void run () { + 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()); + } + } + } + } + + public static void show(Component frameComp, AltosBTKnown known) { + Frame frame = JOptionPane.getFrameForComponent(frameComp); + AltosBTManage dialog; + + dialog = new AltosBTManage(frame, known); + dialog.setVisible(true); + } + + 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(); + + listeners = new LinkedList<ActionListener>(); + + found_devices = new LinkedBlockingQueue<AltosBTDevice>(); + + 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; + c.weightx = 0; + c.weighty = 0; + 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; + c.weightx = 1; + c.weighty = 1; + 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; + c.weightx = 0; + c.weighty = 0; + + 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; + c.weightx = 1; + c.weighty = 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; + c.weightx = 0; + c.weighty = 0; + 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; + c.weightx = 0; + c.weighty = 0; + 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; + c.weightx = 0; + c.weighty = 0; + 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; + c.weightx = 0; + c.weighty = 0; + pane.add(ok_button, c); + + getRootPane().setDefaultButton(ok_button); + + pack(); + setLocationRelativeTo(frame); + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + bt_thread.interrupt(); + setVisible(false); + } + }); + } +} diff --git a/altosuilib/AltosDeviceUIDialog.java b/altosuilib/AltosDeviceUIDialog.java new file mode 100644 index 00000000..3013612a --- /dev/null +++ b/altosuilib/AltosDeviceUIDialog.java @@ -0,0 +1,69 @@ +/* + * Copyright © 2010 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 org.altusmetrum.altosuilib_2; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public class AltosDeviceUIDialog extends AltosDeviceDialog { + + public AltosDevice[] devices() { + java.util.List<AltosDevice> usb_devices = AltosUSBDevice.list(product); + int num_devices = usb_devices.size(); + java.util.List<AltosDevice> bt_devices = AltosBTKnown.bt_known().list(product); + num_devices += bt_devices.size(); + AltosDevice[] devices = new AltosDevice[num_devices]; + + 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; + } + + public void add_bluetooth() { + JButton manage_bluetooth_button = new JButton("Manage Bluetooth"); + manage_bluetooth_button.setActionCommand("manage"); + manage_bluetooth_button.addActionListener(this); + buttonPane.add(manage_bluetooth_button); + buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); + } + + public void actionPerformed(ActionEvent e) { + super.actionPerformed(e); + if ("manage".equals(e.getActionCommand())) { + AltosBTManage.show(frame, AltosBTKnown.bt_known()); + update_devices(); + } + } + + public AltosDeviceUIDialog (Frame in_frame, Component location, int in_product) { + super(in_frame, location, in_product); + } + + public static AltosDevice show (Component frameComp, int product) { + Frame frame = JOptionPane.getFrameForComponent(frameComp); + AltosDeviceUIDialog dialog; + + dialog = new AltosDeviceUIDialog(frame, frameComp, product); + dialog.setVisible(true); + return dialog.getValue(); + } +} diff --git a/altosuilib/AltosSerial.java b/altosuilib/AltosSerial.java new file mode 100644 index 00000000..0632ca70 --- /dev/null +++ b/altosuilib/AltosSerial.java @@ -0,0 +1,208 @@ +/* + * Copyright © 2010 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. + */ + +/* + * Deal with TeleDongle on a serial port + */ + +package org.altusmetrum.altosuilib_2; + +import java.io.*; +import java.util.*; +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_4.*; +import libaltosJNI.*; + +/* + * This class reads from the serial port and places each received + * line in a queue. Dealing with that queue is left up to other + * threads. + */ + +public class AltosSerial extends AltosLink { + + static java.util.List<String> devices_opened = Collections.synchronizedList(new LinkedList<String>()); + + public AltosDevice device; + SWIGTYPE_p_altos_file altos; + Thread input_thread; + String line; + byte[] line_bytes; + int line_count; + Frame frame; + + public int getchar() { + if (altos == null) + return ERROR; + return libaltos.altos_getchar(altos, 0); + } + + public void flush_output() { + super.flush_output(); + if (altos != null) { + if (libaltos.altos_flush(altos) != 0) + close_serial(); + } + } + + JDialog timeout_dialog; + + private void start_timeout_dialog_internal() { + + Object[] options = { "Cancel" }; + + JOptionPane pane = new JOptionPane(); + pane.setMessage(String.format("Connecting to %s, %7.3f MHz as %s", device.toShortString(), frequency, callsign)); + pane.setOptions(options); + pane.setInitialValue(null); + + timeout_dialog = pane.createDialog(frame, "Connecting..."); + + timeout_dialog.setVisible(true); + + Object o = pane.getValue(); + if (o == null) + return; + if (options[0].equals(o)) + reply_abort = true; + timeout_dialog.dispose(); + timeout_dialog = null; + } + + /* + * These are required by the AltosLink implementation + */ + + public boolean can_cancel_reply() { + /* + * Can cancel any replies not called from the dispatch thread + */ + return !SwingUtilities.isEventDispatchThread(); + } + + public boolean show_reply_timeout() { + if (!SwingUtilities.isEventDispatchThread() && frame != null) { + Runnable r = new Runnable() { + public void run() { + start_timeout_dialog_internal(); + } + }; + SwingUtilities.invokeLater(r); + return true; + } + return false; + } + + public void hide_reply_timeout() { + Runnable r = new Runnable() { + public void run() { + timeout_dialog.setVisible(false); + } + }; + SwingUtilities.invokeLater(r); + } + + private void close_serial() { + synchronized (devices_opened) { + devices_opened.remove(device.getPath()); + } + if (altos != null) { + libaltos.altos_free(altos); + altos = null; + } + abort_reply(); + } + + public void close() { + if (remote) { + try { + stop_remote(); + } catch (InterruptedException ie) { + } + } + if (in_reply != 0) + System.out.printf("Uh-oh. Closing active serial device\n"); + + close_serial(); + + if (input_thread != null) { + try { + input_thread.interrupt(); + input_thread.join(); + } catch (InterruptedException ie) { + } + input_thread = null; + } + if (debug) + System.out.printf("Closing %s\n", device.getPath()); + } + + private void putc(char c) { + if (altos != null) + if (libaltos.altos_putchar(altos, c) != 0) + close_serial(); + } + + public void putchar(byte c) { + if (altos != null) { + if (debug) + System.out.printf(" %02x", (int) c & 0xff); + if (libaltos.altos_putchar(altos, (char) c) != 0) + close_serial(); + } + } + + public void print(String data) { + for (int i = 0; i < data.length(); i++) + putc(data.charAt(i)); + } + + private void open() throws FileNotFoundException, AltosSerialInUseException { + synchronized (devices_opened) { + if (devices_opened.contains(device.getPath())) + throw new AltosSerialInUseException(device); + devices_opened.add(device.getPath()); + } + altos = device.open(); + if (altos == null) { + final String message = device.getErrorString(); + close(); + throw new FileNotFoundException(String.format("%s (%s)", + device.toShortString(), message)); + } + if (debug) + System.out.printf("Open %s\n", device.getPath()); + input_thread = new Thread(this); + input_thread.start(); + print("~\nE 0\n"); + set_monitor(false); + flush_output(); + } + + public void set_frame(Frame in_frame) { + frame = in_frame; + } + + public AltosSerial(AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException { + device = in_device; + frame = null; + serial = device.getSerial(); + name = device.toShortString(); + open(); + } +} diff --git a/altosuilib/AltosSerialInUseException.java b/altosuilib/AltosSerialInUseException.java new file mode 100644 index 00000000..1e8207d1 --- /dev/null +++ b/altosuilib/AltosSerialInUseException.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2010 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 org.altusmetrum.altosuilib_2; + +public class AltosSerialInUseException extends Exception { + public AltosDevice device; + + public AltosSerialInUseException (AltosDevice in_device) { + device = in_device; + } +} diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am index 10b756b8..fe0c3ec7 100644 --- a/altosuilib/Makefile.am +++ b/altosuilib/Makefile.am @@ -40,7 +40,15 @@ altosuilib_JAVA = \ AltosSiteMapImage.java \ AltosVoice.java \ AltosDisplayThread.java \ - AltosFreqList.java + AltosDeviceUIDialog.java \ + AltosFreqList.java \ + AltosSerial.java \ + AltosSerialInUseException.java \ + AltosBTDevice.java \ + AltosBTDeviceIterator.java \ + AltosBTManage.java \ + AltosBTKnown.java + JAR=altosuilib_$(ALTOSUILIB_VERSION).jar |
