/*
This file is part of JFLICKS.
JFLICKS 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, either version 3 of the License, or
(at your option) any later version.
JFLICKS 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 JFLICKS. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jflicks.rc.lirc;
import java.awt.AWTException;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.URL;
import java.util.Hashtable;
import org.lirc.LIRCException;
import org.lirc.util.IRActionListener;
import org.lirc.util.SimpleLIRCClient;
import org.jflicks.rc.Display;
import org.jflicks.rc.RC;
import org.jflicks.job.AbstractJob;
import org.jflicks.job.JobManager;
import org.jflicks.util.LogUtil;
import org.jflicks.util.RuntimeId;
import org.osgi.framework.BundleContext;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.util.tracker.ServiceTracker;
/**
* A job that handles all lirc actions.
*
* @author Doug Barnum
* @version 1.0
*/
public class LircRCJob extends AbstractJob implements IRActionListener,
PropertyChangeListener {
private String configuration;
private SimpleLIRCClient simpleLIRCClient;
private Robot robot;
private Display display;
private BundleContext bundleContext;
private ServiceTracker eventServiceTracker;
private LircRC lircRC;
/**
* Simple contructor with a BundleContext supplied.
*
* @param bc A given BundleContext.
* @param rc The RC instance we get user settings from.
*/
public LircRCJob(BundleContext bc, LircRC rc) {
setDisplay(new Display());
setSleepTime(30000);
setBundleContext(bc);
setLircRC(rc);
setConfiguration("conf/LircJob.lircrc");
try {
setRobot(new Robot());
ServiceTracker est =
new ServiceTracker(bc, EventAdmin.class.getName(), null);
setEventServiceTracker(est);
} catch (AWTException ex) {
throw new RuntimeException(ex);
}
}
/**
* Simple contructor with a BundleContext and configuration file
* supplied.
*
* @param bc A given BundleContext.
* @param rc The RC instance we get user settings from.
* @param configuration A lirc configuration file.
*/
public LircRCJob(BundleContext bc, LircRC rc, String configuration) {
this(bc, rc);
setConfiguration(configuration);
}
private LircRC getLircRC() {
return (lircRC);
}
private void setLircRC(LircRC rc) {
lircRC = rc;
if (rc != null) {
rc.addPropertyChangeListener("MouseControl", this);
}
}
private boolean isMouseControl() {
boolean result = false;
LircRC rc = getLircRC();
if (rc != null) {
result = rc.isMouseControl();
}
return (result);
}
private boolean isKeyboardControl() {
boolean result = false;
LircRC rc = getLircRC();
if (rc != null) {
result = rc.isKeyboardControl();
}
return (result);
}
private boolean isEventControl() {
boolean result = false;
LircRC rc = getLircRC();
if (rc != null) {
result = rc.isEventControl();
}
return (result);
}
private Display getDisplay() {
return (display);
}
private void setDisplay(Display d) {
display = d;
}
private ServiceTracker getEventServiceTracker() {
return (eventServiceTracker);
}
private void setEventServiceTracker(ServiceTracker est) {
eventServiceTracker = est;
}
private BundleContext getBundleContext() {
return (bundleContext);
}
private void setBundleContext(BundleContext bc) {
bundleContext = bc;
}
/**
* The job needs a configuration file to configure lirc properly. It
* defaults to conf/LircJob.lircrc.
*
* @return The configuration as a string.
*/
public String getConfiguration() {
return (configuration);
}
/**
* The job needs a configuration file to configure lirc properly. It
* defaults to conf/LircJob.lircrc.
*
* @param s The configuration as a string.
*/
public void setConfiguration(String s) {
configuration = s;
}
private SimpleLIRCClient getSimpleLIRCClient() {
return (simpleLIRCClient);
}
private void setSimpleLIRCClient(SimpleLIRCClient c) {
simpleLIRCClient = c;
}
private Robot getRobot() {
return (robot);
}
private void setRobot(Robot r) {
robot = r;
}
/**
* {@inheritDoc}
*/
public void start() {
ServiceTracker st = getEventServiceTracker();
if (st != null) {
st.open();
}
String path = getConfiguration();
if (path != null) {
try {
File f = new File(path);
if ((f.exists()) && (f.isFile())) {
SimpleLIRCClient c = new SimpleLIRCClient(path);
c.addIRActionListener(this);
setSimpleLIRCClient(c);
setTerminate(false);
} else {
URL url = getClass().getResource("LircJob.lircrc");
if (url != null) {
InputStreamReader isr = new InputStreamReader(
url.openStream());
SimpleLIRCClient c = new SimpleLIRCClient(null, isr);
c.addIRActionListener(this);
setSimpleLIRCClient(c);
setTerminate(false);
}
}
} catch (IOException ex) {
LogUtil.log(LogUtil.WARNING, ex.getMessage());
} catch (LIRCException ex) {
LogUtil.log(LogUtil.WARNING, ex.getMessage());
}
}
}
/**
* {@inheritDoc}
*/
public void run() {
while (!isTerminate()) {
JobManager.sleep(getSleepTime());
}
}
/**
* {@inheritDoc}
*/
public void stop() {
ServiceTracker st = getEventServiceTracker();
if (st != null) {
st.close();
}
SimpleLIRCClient c = getSimpleLIRCClient();
if (c != null) {
c.stopListening();
setSimpleLIRCClient(null);
}
setTerminate(true);
}
private void keyboardMoveUp() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getUpKeyEvent());
r.keyRelease(rc.getUpKeyEvent());
}
}
private void keyboardMoveDown() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getDownKeyEvent());
r.keyRelease(rc.getDownKeyEvent());
}
}
private void keyboardMoveLeft() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getLeftKeyEvent());
r.keyRelease(rc.getLeftKeyEvent());
}
}
private void keyboardMoveRight() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getRightKeyEvent());
r.keyRelease(rc.getRightKeyEvent());
}
}
private void keyboardEnter() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getEnterKeyEvent());
r.keyRelease(rc.getEnterKeyEvent());
}
}
private void keyboardEscape() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getEscapeKeyEvent());
r.keyRelease(rc.getEscapeKeyEvent());
}
}
private void keyboardPause() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getPauseKeyEvent());
r.keyRelease(rc.getPauseKeyEvent());
}
}
private void keyboardMaximize() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getMaximizeKeyEvent());
r.keyRelease(rc.getMaximizeKeyEvent());
}
}
private void keyboardInfo() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getInfoKeyEvent());
r.keyRelease(rc.getInfoKeyEvent());
}
}
private void keyboardGuide() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getGuideKeyEvent());
r.keyRelease(rc.getGuideKeyEvent());
}
}
private void keyboardPageUp() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getPageUpKeyEvent());
r.keyRelease(rc.getPageUpKeyEvent());
}
}
private void keyboardPageDown() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getPageDownKeyEvent());
r.keyRelease(rc.getPageDownKeyEvent());
}
}
private void keyboardRewind() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getRewindKeyEvent());
r.keyRelease(rc.getRewindKeyEvent());
}
}
private void keyboardForward() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getForwardKeyEvent());
r.keyRelease(rc.getForwardKeyEvent());
}
}
private void keyboardSkipBackward() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getSkipBackwardKeyEvent());
r.keyRelease(rc.getSkipBackwardKeyEvent());
}
}
private void keyboardSkipForward() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getSkipForwardKeyEvent());
r.keyRelease(rc.getSkipForwardKeyEvent());
}
}
private void keyboardSap() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getSapKeyEvent());
r.keyRelease(rc.getSapKeyEvent());
}
}
private void keyboardAudiosyncPlus() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getAudiosyncPlusKeyEvent());
r.keyRelease(rc.getAudiosyncPlusKeyEvent());
}
}
private void keyboardAudiosyncMinus() {
LircRC rc = getLircRC();
Robot r = getRobot();
if ((rc != null) && (r != null)) {
r.keyPress(rc.getAudiosyncMinusKeyEvent());
r.keyRelease(rc.getAudiosyncMinusKeyEvent());
}
}
private void mouseMoveUp() {
Robot r = getRobot();
Display d = getDisplay();
if ((r != null) && (d != null)) {
Point p = d.getUp();
if (p != null) {
r.mouseMove((int) p.getX(), (int) p.getY());
}
}
}
private void mouseMoveDown() {
Display d = getDisplay();
Robot r = getRobot();
if ((d != null) && (r != null)) {
Point p = d.getDown();
if (p != null) {
r.mouseMove((int) p.getX(), (int) p.getY());
}
}
}
private void mouseMoveLeft() {
Display d = getDisplay();
Robot r = getRobot();
if ((d != null) && (r != null)) {
Point p = d.getLeft();
if (p != null) {
r.mouseMove((int) p.getX(), (int) p.getY());
}
}
}
private void mouseMoveRight() {
Display d = getDisplay();
Robot r = getRobot();
if ((d != null) && (r != null)) {
Point p = d.getRight();
if (p != null) {
r.mouseMove((int) p.getX(), (int) p.getY());
}
}
}
private void mouseEnter() {
Robot r = getRobot();
if (r != null) {
r.mousePress(InputEvent.BUTTON1_MASK);
r.mouseRelease(InputEvent.BUTTON1_MASK);
}
}
private void mouseEscape() {
Robot r = getRobot();
if (r != null) {
r.mousePress(InputEvent.BUTTON3_MASK);
r.mouseRelease(InputEvent.BUTTON3_MASK);
}
}
private void eventMoveUp() {
command(RC.UP_COMMAND);
}
private void eventMoveDown() {
command(RC.DOWN_COMMAND);
}
private void eventMoveLeft() {
command(RC.LEFT_COMMAND);
}
private void eventMoveRight() {
command(RC.RIGHT_COMMAND);
}
private void eventEnter() {
command(RC.ENTER_COMMAND);
}
private void eventEscape() {
command(RC.ESCAPE_COMMAND);
}
private void eventPause() {
command(RC.PAUSE_COMMAND);
}
private void eventMaximize() {
command(RC.MAXIMIZE_COMMAND);
}
private void eventInfo() {
command(RC.INFO_COMMAND);
}
private void eventGuide() {
command(RC.GUIDE_COMMAND);
}
private void eventPageUp() {
command(RC.PAGE_UP_COMMAND);
}
private void eventPageDown() {
command(RC.PAGE_DOWN_COMMAND);
}
private void eventRewind() {
command(RC.REWIND_COMMAND);
}
private void eventForward() {
command(RC.FORWARD_COMMAND);
}
private void eventSkipBackward() {
command(RC.SKIPBACKWARD_COMMAND);
}
private void eventSkipForward() {
command(RC.SKIPFORWARD_COMMAND);
}
private void eventSap() {
command(RC.SAP_COMMAND);
}
private void eventAudiosyncPlus() {
command(RC.AUDIOSYNC_PLUS_COMMAND);
}
private void eventAudiosyncMinus() {
command(RC.AUDIOSYNC_MINUS_COMMAND);
}
private void moveUp() {
if (isMouseControl()) {
mouseMoveUp();
}
if (isKeyboardControl()) {
keyboardMoveUp();
}
if (isEventControl()) {
eventMoveUp();
}
}
private void moveDown() {
if (isMouseControl()) {
mouseMoveDown();
}
if (isKeyboardControl()) {
keyboardMoveDown();
}
if (isEventControl()) {
eventMoveDown();
}
}
private void moveLeft() {
if (isMouseControl()) {
mouseMoveLeft();
}
if (isKeyboardControl()) {
keyboardMoveLeft();
}
if (isEventControl()) {
eventMoveLeft();
}
}
private void moveRight() {
if (isMouseControl()) {
mouseMoveRight();
}
if (isKeyboardControl()) {
keyboardMoveRight();
}
if (isEventControl()) {
eventMoveRight();
}
}
private void enter() {
if (isMouseControl()) {
mouseEnter();
}
if (isKeyboardControl()) {
keyboardEnter();
}
if (isEventControl()) {
eventEnter();
}
}
private void escape() {
if (isMouseControl()) {
mouseEscape();
}
if (isKeyboardControl()) {
keyboardEscape();
}
if (isEventControl()) {
eventEscape();
}
}
private void pause() {
if (isKeyboardControl()) {
keyboardPause();
}
if (isEventControl()) {
eventPause();
}
}
private void maximize() {
if (isKeyboardControl()) {
keyboardMaximize();
}
if (isEventControl()) {
eventMaximize();
}
}
private void info() {
if (isKeyboardControl()) {
keyboardInfo();
}
if (isEventControl()) {
eventInfo();
}
}
private void guide() {
if (isKeyboardControl()) {
keyboardGuide();
}
if (isEventControl()) {
eventGuide();
}
}
private void pageup() {
if (isKeyboardControl()) {
keyboardPageUp();
}
if (isEventControl()) {
eventPageUp();
}
}
private void pagedown() {
if (isKeyboardControl()) {
keyboardPageDown();
}
if (isEventControl()) {
eventPageDown();
}
}
private void rewind() {
if (isKeyboardControl()) {
keyboardRewind();
}
if (isEventControl()) {
eventRewind();
}
}
private void forward() {
if (isKeyboardControl()) {
keyboardForward();
}
if (isEventControl()) {
eventForward();
}
}
private void skipbackward() {
if (isKeyboardControl()) {
keyboardSkipBackward();
}
if (isEventControl()) {
eventSkipBackward();
}
}
private void skipforward() {
if (isKeyboardControl()) {
keyboardSkipForward();
}
if (isEventControl()) {
eventSkipForward();
}
}
private void sap() {
if (isKeyboardControl()) {
keyboardSap();
}
if (isEventControl()) {
eventSap();
}
}
private void audiosyncplus() {
if (isKeyboardControl()) {
keyboardAudiosyncPlus();
}
if (isEventControl()) {
eventAudiosyncPlus();
}
}
private void audiosyncminus() {
if (isKeyboardControl()) {
keyboardAudiosyncMinus();
}
if (isEventControl()) {
eventAudiosyncMinus();
}
}
private void command(String s) {
ServiceTracker st = getEventServiceTracker();
if ((st != null) && (s != null)) {
EventAdmin ea = (EventAdmin) st.getService();
if (ea != null) {
Hashtable<String, String> props =
new Hashtable<String, String>();
props.put("command", s);
props.put("runtimeid", RuntimeId.getInstance().getId());
Event evt = new Event("org/jflicks/rc/COMMAND", props);
ea.postEvent(evt);
}
}
}
/**
* The action received from lirc.
*
* @param command The action string configured for the button that the
* user pressed. It should then be mapped to an internal method here.
*/
public void action(String command) {
if (command != null) {
if (command.equalsIgnoreCase(RC.UP_COMMAND)) {
moveUp();
} else if (command.equalsIgnoreCase(RC.DOWN_COMMAND)) {
moveDown();
} else if (command.equalsIgnoreCase(RC.LEFT_COMMAND)) {
moveLeft();
} else if (command.equalsIgnoreCase(RC.RIGHT_COMMAND)) {
moveRight();
} else if (command.equalsIgnoreCase(RC.ENTER_COMMAND)) {
enter();
} else if (command.equalsIgnoreCase(RC.ESCAPE_COMMAND)) {
escape();
} else if (command.equalsIgnoreCase(RC.PAUSE_COMMAND)) {
pause();
} else if (command.equalsIgnoreCase(RC.MAXIMIZE_COMMAND)) {
maximize();
} else if (command.equalsIgnoreCase(RC.INFO_COMMAND)) {
info();
} else if (command.equalsIgnoreCase(RC.GUIDE_COMMAND)) {
guide();
} else if (command.equalsIgnoreCase(RC.PAGE_UP_COMMAND)) {
pageup();
} else if (command.equalsIgnoreCase(RC.PAGE_DOWN_COMMAND)) {
pagedown();
} else if (command.equalsIgnoreCase(RC.REWIND_COMMAND)) {
rewind();
} else if (command.equalsIgnoreCase(RC.FORWARD_COMMAND)) {
forward();
} else if (command.equalsIgnoreCase(RC.SKIPBACKWARD_COMMAND)) {
skipbackward();
} else if (command.equalsIgnoreCase(RC.SKIPFORWARD_COMMAND)) {
skipforward();
} else if (command.equalsIgnoreCase(RC.SAP_COMMAND)) {
sap();
} else if (command.equalsIgnoreCase(RC.AUDIOSYNC_PLUS_COMMAND)) {
audiosyncplus();
} else if (command.equalsIgnoreCase(RC.AUDIOSYNC_MINUS_COMMAND)) {
audiosyncminus();
}
}
}
/**
* We need to know when the user has turned on mouse control so we
* can locate the mouse and initialize it's location in our Display.
*
* @param event A PropertyChangeEvent instance.
*/
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals("MouseControl")) {
Boolean bobj = (Boolean) event.getNewValue();
if (bobj.booleanValue()) {
Display d = getDisplay();
if (d != null) {
d.fromMouse();
}
}
}
}
}