diff --git a/java/client.bat b/java/client.bat index 709c4b3..8c54659 100644 --- a/java/client.bat +++ b/java/client.bat @@ -1,3 +1,4 @@ +@echo off set path=%path%;native -java -cp bin;cfg;resource;lib/jacob-1.15-M3.jar;lib/TableLayout.jar;lib/nativecall-0.4.1.jar;lib/nativeloader-200505172341.jar pm.Client +java -cp bin;cfg;resource;lib/commons-logging-1.1.1.jar;lib/jacob-1.15-M3.jar;lib/TableLayout.jar;lib/nativecall-0.4.1.jar;lib/nativeloader-200505172341.jar mimis.Client pause \ No newline at end of file diff --git a/java/resource/kop.png b/java/resource/kop.png new file mode 100644 index 0000000..54fa21d Binary files /dev/null and b/java/resource/kop.png differ diff --git a/java/src/mimis/Application.java b/java/src/mimis/Application.java index 488f855..201990a 100644 --- a/java/src/mimis/Application.java +++ b/java/src/mimis/Application.java @@ -2,6 +2,7 @@ package mimis; import mimis.event.EventHandler; import mimis.event.Task; +import mimis.event.feedback.TextFeedback; import mimis.exception.WorkerException; import mimis.exception.worker.DeactivateException; import mimis.manager.Exitable; @@ -29,10 +30,11 @@ public abstract class Application extends EventHandler implements Titled, Exitab case ACTIVATE: if (task.getSignal().equals(Signal.BEGIN)) { try { - log.debug(active()); if (active()) { + eventRouter.add(new TextFeedback("Deactivate application")); deactivate(); } else { + eventRouter.add(new TextFeedback("Activate application")); activate(); } } catch (WorkerException e) { diff --git a/java/src/mimis/Device.java b/java/src/mimis/Device.java index 765e592..8eb1d11 100644 --- a/java/src/mimis/Device.java +++ b/java/src/mimis/Device.java @@ -1,7 +1,6 @@ package mimis; import mimis.event.EventHandler; -import mimis.exception.worker.ActivateException; import mimis.exception.worker.DeactivateException; import mimis.manager.Exitable; import mimis.manager.Titled; @@ -15,6 +14,7 @@ public abstract class Device extends EventHandler implements Titled, Exitable { public Device(String title) { this.title = title; + sequenceParser = new SequenceParser(this); } public String title() { @@ -22,11 +22,6 @@ public abstract class Device extends EventHandler implements Titled, Exitable { } /* Worker */ - public void activate() throws ActivateException { - super.activate(); - sequenceParser = new SequenceParser(this); - } - public void deactivate() throws DeactivateException { super.deactivate(); sequenceParser.reset(); diff --git a/java/src/mimis/GUI.java b/java/src/mimis/GUI.java index 3ebd0a8..59494bb 100644 --- a/java/src/mimis/GUI.java +++ b/java/src/mimis/GUI.java @@ -12,6 +12,7 @@ import javax.swing.SwingConstants; import javax.swing.WindowConstants; import mimis.exception.worker.DeactivateException; +import mimis.util.Swing; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -30,6 +31,7 @@ public class GUI extends JFrame { public GUI(Mimis mimis, Manager applicationManager, Manager deviceManager) { super(TITLE); this.mimis = mimis; + setIconImage(Swing.getImage("kop.png")); createFrame(applicationManager, deviceManager); } diff --git a/java/src/mimis/Mimis.java b/java/src/mimis/Mimis.java index 76d6773..3305a87 100644 --- a/java/src/mimis/Mimis.java +++ b/java/src/mimis/Mimis.java @@ -5,7 +5,7 @@ import mimis.event.EventRouter; import mimis.event.Feedback; import mimis.exception.worker.ActivateException; import mimis.exception.worker.DeactivateException; -import mimis.feedback.TextFeedback; +import mimis.event.feedback.TextFeedback; import mimis.sequence.SequenceParser; import mimis.util.ArrayCycle; import mimis.value.Action; diff --git a/java/src/mimis/application/cmd/CMDApplication.java b/java/src/mimis/application/cmd/CMDApplication.java index c6dd2f7..e9d218a 100644 --- a/java/src/mimis/application/cmd/CMDApplication.java +++ b/java/src/mimis/application/cmd/CMDApplication.java @@ -26,6 +26,9 @@ public abstract class CMDApplication extends Application { super.activate(); String key = String.format("%s\\%s", REGISTRY, program); String path = Native.getValue(key); + if (path == null) { + throw new ActivateException(); + } try { String command = path.startsWith("\"") ? path : String.format("\"%s\"", path); command = Native.replaceVariables(command); diff --git a/java/src/mimis/application/cmd/windows/WindowsApplication.java b/java/src/mimis/application/cmd/windows/WindowsApplication.java index 7350a33..def0127 100644 --- a/java/src/mimis/application/cmd/windows/WindowsApplication.java +++ b/java/src/mimis/application/cmd/windows/WindowsApplication.java @@ -29,7 +29,6 @@ public abstract class WindowsApplication extends CMDApplication { public void activate() throws ActivateException { super.activate(); handle = Windows.findWindow(name, null); - log.info(handle); if (handle < 1) { sleep(START_SLEEP); handle = Windows.findWindow(name, null); @@ -66,13 +65,13 @@ public abstract class WindowsApplication extends CMDApplication { //return Windows.sendMessage(handle, Windows.WM_USER + wParam, 0, 0); } - protected void key(Type key, int code) { + protected void key(Type type, int code) { int scanCode = Windows.mapVirtualKey(code, Windows.MAPVK_VK_TO_VSC); - Windows.postMessage(handle, key.getCode(), code, 1 | (scanCode << 16)); + Windows.postMessage(handle, type.getCode(), code, 1 | (scanCode << 16)); } - protected void key(Type key, char character) { - key(key, (int) Character.toUpperCase(character)); + protected void key(Type type, char character) { + key(type, (int) Character.toUpperCase(character)); } protected void key(Type key, Key virtualKey) { diff --git a/java/src/mimis/application/cmd/windows/gomplayer/GomPlayerApplication.java b/java/src/mimis/application/cmd/windows/gomplayer/GomPlayerApplication.java index c06d746..98e44d3 100644 --- a/java/src/mimis/application/cmd/windows/gomplayer/GomPlayerApplication.java +++ b/java/src/mimis/application/cmd/windows/gomplayer/GomPlayerApplication.java @@ -1,38 +1,127 @@ package mimis.application.cmd.windows.gomplayer; +import mimis.Worker; import mimis.application.cmd.windows.WindowsApplication; +import mimis.exception.worker.ActivateException; +import mimis.exception.worker.DeactivateException; import mimis.value.Action; +import mimis.value.Amount; public class GomPlayerApplication extends WindowsApplication { protected final static String PROGRAM = "GOM.exe"; protected final static String TITLE = "GOM Player"; protected final static String NAME = "GomPlayer1.x"; + protected static final int VOLUME_SLEEP = 100; + protected static final int SEEK_SLEEP = 100; + + protected VolumeWorker volumeWorker; + protected SeekWorker seekWorker; + public GomPlayerApplication() { super(PROGRAM, TITLE, NAME); + volumeWorker = new VolumeWorker(); + seekWorker = new SeekWorker(); } public void begin(Action action) { log.trace("GomPlayerApplication begin: " + action); + try { + switch (action) { + case VOLUME_UP: + volumeWorker.activate(1); + break; + case VOLUME_DOWN: + volumeWorker.activate(-1); + break; + case FORWARD: + seekWorker.activate(Amount.SMALL, 1); + break; + case REWIND: + seekWorker.activate(Amount.SMALL, -1); + break; + case NEXT: + seekWorker.activate(Amount.MEDIUM, 1); + break; + case PREVIOUS: + seekWorker.activate(Amount.MEDIUM, -1); + break; + } + } catch (ActivateException e) { + log.error(e); + } + } + + public void end(Action action) { + log.trace("GomPlayerApplication end: " + action); switch (action) { case PLAY: command(0x800C); break; - case FORWARD: - command(0x8009); - break; - case REWIND: - command(0x8008); - break; case MUTE: command(0x8016); break; - case VOLUME_UP: - command(0x8014); + case FORWARD: + case REWIND: + case NEXT: + case PREVIOUS: + try { + seekWorker.deactivate(); + } catch (DeactivateException e) { + log.error(e); + } break; + case VOLUME_UP: case VOLUME_DOWN: - command(0x8013); + try { + volumeWorker.deactivate(); + } catch (DeactivateException e) { + log.error(e); + } + break; + case FULLSCREEN: + command(0x8154); break; } } + + protected class VolumeWorker extends Worker { + protected int volumeChangeSign; + + public void activate(int volumeChangeSign) throws ActivateException { + super.activate(); + this.volumeChangeSign = volumeChangeSign; + } + + public void work() { + command(volumeChangeSign > 0 ? 0x8014 : 0x8013); + sleep(VOLUME_SLEEP); + } + }; + + protected class SeekWorker extends Worker { + protected Amount amount; + protected int seekDirection; + + public void activate(Amount amount, int seekDirection) throws ActivateException { + super.activate(); + this.amount = amount; + this.seekDirection = seekDirection; + } + + public void work() { + switch (amount) { + case SMALL: + command(seekDirection > 0 ? 0x8009 : 0x8008); + break; + case MEDIUM: + command(seekDirection > 0 ? 0x800B : 0x800A); + break; + case LARGE: + command(seekDirection > 0 ? 0x8012 : 0x8011); + break; + } + sleep(SEEK_SLEEP); + } + }; } diff --git a/java/src/mimis/application/cmd/windows/winamp/WinampApplication.java b/java/src/mimis/application/cmd/windows/winamp/WinampApplication.java index 0440d0f..0d19ace 100644 --- a/java/src/mimis/application/cmd/windows/winamp/WinampApplication.java +++ b/java/src/mimis/application/cmd/windows/winamp/WinampApplication.java @@ -40,8 +40,6 @@ public class WinampApplication extends WindowsApplication { protected SeekWorker seekWorker; protected double volume; protected boolean muted; - protected boolean forward; - protected boolean rewind; public WinampApplication() { super(PROGRAM, TITLE, NAME); @@ -59,35 +57,23 @@ public class WinampApplication extends WindowsApplication { public void begin(Action action) { log.trace("WinampApplication begin: " + action); - switch (action) { - case VOLUME_UP: - try { + try { + switch (action) { + case VOLUME_UP: volumeWorker.activate(1); - } catch (ActivateException e) { - log.error(e); - } - break; - case VOLUME_DOWN: - try { + break; + case VOLUME_DOWN: volumeWorker.activate(-1); - } catch (ActivateException e) { - log.error(e); - } - break; - case FORWARD: - try { + break; + case FORWARD: seekWorker.activate(1); - } catch (ActivateException e) { - log.error(e); - } - break; - case REWIND: - try { + break; + case REWIND: seekWorker.activate(-1); - } catch (ActivateException e) { - log.error(e); - } - break; + break; + } + } catch (ActivateException e) { + log.error(e); } } @@ -193,7 +179,7 @@ public class WinampApplication extends WindowsApplication { public void work() { command(seekDirection > 0 ? WINAMP_FFWD5S : WINAMP_REW5S); - sleep(VOLUME_SLEEP); + sleep(SEEK_SLEEP); } }; } diff --git a/java/src/mimis/application/itunes/iTunesApplication.java b/java/src/mimis/application/itunes/iTunesApplication.java index 678f8f0..c4e6505 100644 --- a/java/src/mimis/application/itunes/iTunesApplication.java +++ b/java/src/mimis/application/itunes/iTunesApplication.java @@ -26,19 +26,23 @@ public class iTunesApplication extends Application implements iTunesEventsInterf protected iTunes iTunes; protected VolumeWorker volumeWorker; + protected boolean handle; protected boolean quiting; public iTunesApplication() { super(TITLE); iTunes = new iTunes(); volumeWorker = new VolumeWorker(); - quiting = false; + handle = quiting = false; } public void activate() throws ActivateException { synchronized (iTunes) { iTunes.connect(); - iTunes.addEventHandler(this); + if (!handle) { + iTunes.addEventHandler(this); + handle = true; + } } super.activate(); } diff --git a/java/src/mimis/application/vlc/VLCApplication.java b/java/src/mimis/application/vlc/VLCApplication.java index 2f88953..3498d39 100644 --- a/java/src/mimis/application/vlc/VLCApplication.java +++ b/java/src/mimis/application/vlc/VLCApplication.java @@ -16,7 +16,7 @@ public class VLCApplication extends CMDApplication { protected static final int VOLUME_CHANGE_RATE = 20; protected static final String HOST = "127.0.0.1"; // localhost - protected static final int PORT = 8080; + protected static final int PORT = 1234; protected int volume = 255; protected boolean muted = false; @@ -42,8 +42,8 @@ public class VLCApplication extends CMDApplication { } } - public void action(Action action) { - log.trace("VLCApplication: " + action); + public void end(Action action) { + log.trace("VLCApplication end: " + action); switch (action) { case PLAY: command("pl_pause"); diff --git a/java/src/mimis/device/lirc/LircDevice.java b/java/src/mimis/device/lirc/LircDevice.java index 38baa2c..3149367 100644 --- a/java/src/mimis/device/lirc/LircDevice.java +++ b/java/src/mimis/device/lirc/LircDevice.java @@ -1,5 +1,6 @@ package mimis.device.lirc; +import java.io.IOException; import java.util.HashMap; import mimis.Button; @@ -12,10 +13,12 @@ import mimis.sequence.state.Press; import mimis.sequence.state.Release; import mimis.util.Multiplexer; import mimis.util.multiplexer.SignalListener; +import mimis.util.VBScript; import mimis.value.Signal; public class LircDevice extends Device implements LircButtonListener, SignalListener { protected static final String TITLE = "Lirc"; + protected final static String PROGRAM = "winlirc.exe"; protected Multiplexer multiplexer; protected LircService lircService; @@ -38,12 +41,31 @@ public class LircDevice extends Device implements LircButtonListener, SignalList } public void activate() throws ActivateException { - super.activate(); multiplexer.start(); lircService.activate(); add(eventMapCycle.denonRC176); add(eventMapCycle.philiphsRCLE011); add(eventMapCycle.samsungBN5901015A); + super.activate(); + } + + public boolean active() { + if (active && !lircService.active()) { + active = false; + } else if (!active) { + try { + if (VBScript.isRunning(PROGRAM)) { + try { + activate(); + } catch (ActivateException e) { + log.error(e); + } + } + } catch (IOException e) { + log.error(e); + } + } + return active; } public void deactivate() throws DeactivateException { diff --git a/java/src/mimis/device/lirc/LircService.java b/java/src/mimis/device/lirc/LircService.java index 92d668e..a5ef6ed 100644 --- a/java/src/mimis/device/lirc/LircService.java +++ b/java/src/mimis/device/lirc/LircService.java @@ -74,6 +74,13 @@ public class LircService extends Worker { super.activate(); } + public boolean active() { + if (active && !socket.isConnected()) { + active = false; + } + return active; + } + public void deactivate() throws DeactivateException { try { bufferedReader.close(); diff --git a/java/src/mimis/device/lirc/remote/PhiliphsRCLE011EventMap.java b/java/src/mimis/device/lirc/remote/PhiliphsRCLE011EventMap.java index e9e4aa4..bcb7e75 100644 --- a/java/src/mimis/device/lirc/remote/PhiliphsRCLE011EventMap.java +++ b/java/src/mimis/device/lirc/remote/PhiliphsRCLE011EventMap.java @@ -25,6 +25,7 @@ public class PhiliphsRCLE011EventMap extends EventMap { add(PhiliphsRCLE011Button.VOLUME_UP, new Task(Target.APPLICATION, Action.VOLUME_UP)); add(PhiliphsRCLE011Button.CLOCK, new Task(Target.APPLICATION, Action.REPEAT)); add(PhiliphsRCLE011Button.OUT, new Task(Target.APPLICATION, Action.SHUFFLE)); + add(PhiliphsRCLE011Button.SQUARE, new Task(Target.APPLICATION, Action.FULLSCREEN)); add(PhiliphsRCLE011Button.RED, new Task(Target.APPLICATION, Action.DISLIKE)); add(PhiliphsRCLE011Button.GREEN, new Task(Target.APPLICATION, Action.LIKE)); } diff --git a/java/src/mimis/device/panel/Panel.java b/java/src/mimis/device/panel/Panel.java index d5b7675..dcbb8cd 100644 --- a/java/src/mimis/device/panel/Panel.java +++ b/java/src/mimis/device/panel/Panel.java @@ -2,21 +2,21 @@ package mimis.device.panel; import java.awt.BorderLayout; import java.awt.event.WindowEvent; -import java.net.URL; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.WindowConstants; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import mimis.exception.worker.DeactivateException; +import mimis.util.Swing; import mimis.util.swing.HoldButton; import mimis.util.swing.HoldButtonListener; import mimis.util.swing.ToggleButton; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + public class Panel extends JFrame implements HoldButtonListener { protected static final long serialVersionUID = 1L; protected Log log = LogFactory.getLog(getClass()); @@ -24,7 +24,7 @@ public class Panel extends JFrame implements HoldButtonListener { protected final static String TITLE = "MIMIS Panel Device"; protected PanelDevice panelDevice; - protected ClassLoader classLoader; + protected HoldButton upButton; protected HoldButton previousButton; protected HoldButton rewindButton; @@ -42,7 +42,7 @@ public class Panel extends JFrame implements HoldButtonListener { Panel(PanelDevice panelDevice) { super(TITLE); this.panelDevice = panelDevice; - classLoader = getClass().getClassLoader(); + setIconImage(Swing.getImage("kop.png")); createControls(); layoutControls(); pack(); @@ -51,25 +51,17 @@ public class Panel extends JFrame implements HoldButtonListener { setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); } - protected URL getResource(String name) { - return classLoader.getResource(name); - } - - protected ImageIcon getImageIcon(String name) { - return new ImageIcon(getResource(name)); - } - protected HoldButton getButton(String name, String text) { HoldButton button = new HoldButton(this); - button.setIcon(getImageIcon(name)); + button.setIcon(Swing.getImageIcon(name)); button.setToolTipText(text); button.setFocusPainted(false); return button; } protected ToggleButton getToggleButton(String firstName, String secondName, String text) { - ImageIcon firstImageIcon = getImageIcon(firstName); - ImageIcon secondImageIcon = getImageIcon(secondName); + ImageIcon firstImageIcon = Swing.getImageIcon(firstName); + ImageIcon secondImageIcon = Swing.getImageIcon(secondName); ToggleButton button = new ToggleButton(this, firstImageIcon, secondImageIcon); button.setToolTipText(text); button.setFocusPainted(false); diff --git a/java/src/mimis/feedback/TextFeedback.java b/java/src/mimis/event/feedback/TextFeedback.java similarity index 84% rename from java/src/mimis/feedback/TextFeedback.java rename to java/src/mimis/event/feedback/TextFeedback.java index 24cf0ba..6f8640b 100644 --- a/java/src/mimis/feedback/TextFeedback.java +++ b/java/src/mimis/event/feedback/TextFeedback.java @@ -1,4 +1,4 @@ -package mimis.feedback; +package mimis.event.feedback; import mimis.event.Feedback; diff --git a/java/src/mimis/event/router/LocalRouter.java b/java/src/mimis/event/router/LocalRouter.java index 3702179..72b8d12 100644 --- a/java/src/mimis/event/router/LocalRouter.java +++ b/java/src/mimis/event/router/LocalRouter.java @@ -4,7 +4,7 @@ import mimis.Event; import mimis.event.Task; import mimis.event.EventListener; import mimis.event.EventRouter; -import mimis.feedback.TextFeedback; +import mimis.event.feedback.TextFeedback; import mimis.value.Target; public class LocalRouter extends EventRouter { diff --git a/java/src/mimis/util/Native.java b/java/src/mimis/util/Native.java index a6a32d9..4e0d161 100644 --- a/java/src/mimis/util/Native.java +++ b/java/src/mimis/util/Native.java @@ -1,40 +1,46 @@ package mimis.util; -import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.InputMismatchException; import java.util.Map; import java.util.NoSuchElementException; import java.util.Scanner; public class Native { - public static int getHandle(String name) throws IOException { - File file = new File("native/list.exe"); - Process process = Runtime.getRuntime().exec(file.getPath()); + public static int getHandle(String title) throws IOException { + String command = String.format("native/list.exe w"); + Process process = Runtime.getRuntime().exec(command); Scanner scanner = new Scanner(process.getInputStream()); - ArrayList handleList = new ArrayList(); - ArrayList titleList = new ArrayList(); + scanner.nextLine(); while (scanner.hasNextLine()) { + Scanner line = new Scanner(scanner.nextLine()); + line.useDelimiter("\t"); try { - int handle = new Integer(scanner.nextLine()); - String title = scanner.nextLine(); - if (title.contains(name)) { - handleList.add(handle); - titleList.add(title); + int handle = line.nextInt(); + line.nextInt(); + if (line.hasNext() && line.next().equals(title)) { + return handle; } } catch (InputMismatchException e) {} } - int count = handleList.size(); - if (count == 1) { - return handleList.get(0); + return -1; + } + + public static String getProgram(int processId) throws IOException { + String command = String.format("native/list.exe p"); + Process process = Runtime.getRuntime().exec(command); + Scanner scanner = new Scanner(process.getInputStream()); + scanner.nextLine(); + while (scanner.hasNextLine()) { + Scanner line = new Scanner(scanner.nextLine()); + line.useDelimiter("\t"); + try { + if (line.nextInt() == processId) { + return line.next(); + } + } catch (InputMismatchException e) {} } - for (int i = 0; i < count; ++i) { - if (titleList.get(i).endsWith(name)) { - return handleList.get(i); - } - } - return count > 0 ? handleList.get(0) : -1; + return null; } public static String getValue(String key, String name) { @@ -60,7 +66,7 @@ public class Native { } public static String getValue(String key) { - return getValue(key, "(Default"); + return getValue(key, "(Default)"); } public static String replaceVariables(String string) { diff --git a/java/src/mimis/util/Swing.java b/java/src/mimis/util/Swing.java new file mode 100644 index 0000000..0c837b1 --- /dev/null +++ b/java/src/mimis/util/Swing.java @@ -0,0 +1,29 @@ +package mimis.util; + +import java.awt.Image; +import java.awt.Toolkit; +import java.net.URL; + +import javax.swing.ImageIcon; + +public class Swing { + protected static ClassLoader classLoader; + protected static Toolkit toolkit; + + static { + classLoader = Swing.class.getClassLoader(); + toolkit = Toolkit.getDefaultToolkit(); + } + + public static URL getResource(String name) { + return classLoader.getResource(name); + } + + public static Image getImage(String name) { + return toolkit.getImage((getResource(name))); + } + + public static ImageIcon getImageIcon(String name) { + return new ImageIcon(getResource(name)); + } +} diff --git a/java/src/mimis/value/Amount.java b/java/src/mimis/value/Amount.java new file mode 100644 index 0000000..77c654b --- /dev/null +++ b/java/src/mimis/value/Amount.java @@ -0,0 +1,5 @@ +package mimis.value; + +public enum Amount { + SMALL, MEDIUM, LARGE +}