/
TSPTT.java
138 lines (120 loc) · 4.26 KB
/
TSPTT.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* Copyright (c) 2011, Dominic Cleal.
*
* Released under the 2-clause BSD licence, see LICENCE.
*/
package com.m0dlx.tsptt;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.Robot;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.InputStream;
/**
* Runs a background task that listens to COM3 for a single digit to know when
* to turn on and off the TeamSpeak PTT.
*
* Uses F5 as the PTT key (to be configured in TS) and COM3 as the serial port.
*
* Requires the rxtx serial library (tested with Cloudhopper x86 binaries):
* http://rxtx.qbang.org/wiki/index.php/Download
*/
public class TSPTT {
private static int KEY_CODE = KeyEvent.VK_F5;
private static String PORT_NAME =
System.getProperty("os.name").startsWith("Windows")
? "COM3" : "/dev/ttyUSB0";
private int keyCode_;
private Robot robot_ = new Robot();
private SerialPort serial_;
private Thread reader_ = Thread.currentThread();
/**
* Usage: TSPTT [COM port] [Key code (int)]
*/
public static void main(String[] args) throws Exception {
if (args.length > 0)
PORT_NAME = args[0];
if (args.length > 1)
KEY_CODE = Integer.parseInt(args[1]);
TSPTT ptt = new TSPTT(PORT_NAME, KEY_CODE);
ptt.monitor();
}
public TSPTT(String portName, int keyCode) throws Exception {
keyCode_ = keyCode;
initSystemTray();
serial_ = initSerial(portName);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
reader_.interrupt(); // stop blocking thread
robot_.keyRelease(keyCode_); // stop hanging keys
serial_.close();
}
}));
}
/** Configure Arduino 9600 8n1 serial connection with rxtx */
private SerialPort initSerial(String portName) throws Exception {
CommPortIdentifier portIdentifier =
CommPortIdentifier.getPortIdentifier(portName);
if (portIdentifier.isCurrentlyOwned())
{
System.err.println("Error: Port " + portName +
" is currently in use");
System.exit(1);
}
SerialPort serialPort = (SerialPort)
portIdentifier.open(this.getClass().getName(), 2000);
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// Set timeout to ensure reader thread doesn't block forever, as rxtx
// ignores interrupts
serialPort.enableReceiveTimeout(1000);
return serialPort;
}
/** Read switch state and press keys, until the thread is interrupted */
public void monitor() throws InterruptedException, IOException {
InputStream is = serial_.getInputStream();
int data;
while (!Thread.currentThread().isInterrupted()) {
data = is.read(); // timeout set above
if (data > 0)
robot_.keyPress(keyCode_);
else if (data == 0)
robot_.keyRelease(keyCode_);
}
}
/** Add a simple system tray icon to close TSPTT easily */
private void initSystemTray() {
if (!SystemTray.isSupported()) return;
PopupMenu popup = new PopupMenu();
MenuItem exitItem = new MenuItem("Exit");
exitItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
popup.add(exitItem);
Image image = Toolkit.getDefaultToolkit().getImage(
TSPTT.class.getResource("icon.png")
);
TrayIcon trayIcon = new TrayIcon(image, "TS PTT", popup);
trayIcon.setImageAutoSize(true);
try {
SystemTray.getSystemTray().add(trayIcon);
} catch (AWTException e) {
System.err.println(e);
}
}
}