From f1a2432f84f68d8ba48fb40ebe19abb75b67c532 Mon Sep 17 00:00:00 2001 From: Iwan Timmer Date: Tue, 7 Jan 2014 01:40:51 +0100 Subject: [PATCH] Convert Limelight to command line application --- src/com/limelight/Limelight.java | 124 +++---- src/com/limelight/gui/GamepadConfigFrame.java | 342 ------------------ src/com/limelight/gui/MainFrame.java | 226 ------------ src/com/limelight/gui/PreferencesFrame.java | 111 ------ src/com/limelight/gui/StreamFrame.java | 287 --------------- 5 files changed, 57 insertions(+), 1033 deletions(-) delete mode 100644 src/com/limelight/gui/GamepadConfigFrame.java delete mode 100644 src/com/limelight/gui/MainFrame.java delete mode 100644 src/com/limelight/gui/PreferencesFrame.java delete mode 100644 src/com/limelight/gui/StreamFrame.java diff --git a/src/com/limelight/Limelight.java b/src/com/limelight/Limelight.java index 34f51fd..d46652d 100644 --- a/src/com/limelight/Limelight.java +++ b/src/com/limelight/Limelight.java @@ -4,14 +4,8 @@ import java.io.File; import java.io.IOException; import java.io.PrintStream; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.UIManager; - import com.limelight.binding.LibraryHelper; import com.limelight.binding.PlatformBinding; -import com.limelight.gui.MainFrame; -import com.limelight.gui.StreamFrame; import com.limelight.input.gamepad.Gamepad; import com.limelight.input.gamepad.GamepadListener; import com.limelight.input.gamepad.NativeGamepad; @@ -19,9 +13,14 @@ import com.limelight.nvstream.NvConnection; import com.limelight.nvstream.NvConnectionListener; import com.limelight.nvstream.StreamConfiguration; import com.limelight.nvstream.av.video.VideoDecoderRenderer; +import com.limelight.nvstream.http.NvHTTP; import com.limelight.settings.PreferencesManager; import com.limelight.settings.PreferencesManager.Preferences; import com.limelight.settings.PreferencesManager.Preferences.Resolution; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import org.xmlpull.v1.XmlPullParserException; /** * Main class for Limelight-pc contains methods for starting the application as well @@ -31,13 +30,10 @@ import com.limelight.settings.PreferencesManager.Preferences.Resolution; */ public class Limelight implements NvConnectionListener { public static final double VERSION = 1.0; - public static boolean COMMAND_LINE_LAUNCH = false; private String host; - private StreamFrame streamFrame; private NvConnection conn; private boolean connectionTerminating; - private static JFrame limeFrame; /** * Constructs a new instance based on the given host @@ -51,11 +47,8 @@ public class Limelight implements NvConnectionListener { * Creates a connection to the host and starts up the stream. */ private void startUp(StreamConfiguration streamConfig, boolean fullscreen) { - streamFrame = new StreamFrame(); - conn = new NvConnection(host, this, streamConfig); - streamFrame.build(this, conn, streamConfig, fullscreen); - conn.start(PlatformBinding.getDeviceName(), streamFrame, + conn.start(PlatformBinding.getDeviceName(), null, VideoDecoderRenderer.FLAG_PREFER_QUALITY, PlatformBinding.getAudioRenderer(), PlatformBinding.getVideoDecoderRenderer()); @@ -63,6 +56,46 @@ public class Limelight implements NvConnectionListener { GamepadListener.getInstance().addDeviceListener(new Gamepad(conn)); } + private void pair() { + String macAddress; + try { + macAddress = NvConnection.getMacAddressString(); + } catch (SocketException e) { + e.printStackTrace(); + return; + } + + if (macAddress == null) { + displayError("Pair", "Couldn't find a MAC address"); + return; + } + + NvHTTP httpConn; + + try { + httpConn = new NvHTTP(InetAddress.getByName(host), + macAddress, PlatformBinding.getDeviceName()); + try { + if (httpConn.getPairState()) { + displayError("Pair", "Already paired"); + } else { + int session = httpConn.getSessionId(); + if (session == 0) { + displayError("Pair", "Pairing was declined by the target"); + } else { + displayMessage("Pairing was successful"); + } + } + } catch (IOException e) { + displayError("Pair", e.getMessage()); + } catch (XmlPullParserException e) { + displayError("Pair", e.getMessage()); + } + } catch (UnknownHostException e1) { + displayError("Pair", "Failed to resolve host"); + } + } + /* * Creates a StreamConfiguration given a Resolution. * Used to specify what kind of stream will be used. @@ -82,15 +115,6 @@ public class Limelight implements NvConnectionListener { return null; } } - - /* - * Creates the main frame for the application. - */ - private static void createFrame() { - MainFrame main = new MainFrame(); - main.build(); - limeFrame = main.getLimeFrame(); - } /** * Creates a new instance and starts the stream. @@ -111,50 +135,16 @@ public class Limelight implements NvConnectionListener { * @param args unused. */ public static void main(String args[]) { - // Redirect logging to a file if we're running from a JAR - if (LibraryHelper.isRunningFromJar()) { - try { - System.setErr(new PrintStream(new File("error.log"))); - System.setOut(new PrintStream(new File("output.log"))); - } catch (IOException e) { - } - } - - //fix the menu bar if we are running in osx - if (System.getProperty("os.name").contains("Mac OS X")) { - // take the menu bar off the jframe - System.setProperty("apple.laf.useScreenMenuBar", "true"); - - // set the name of the application menu item - System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Limelight"); - - } else { - try { - UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); - } catch (Exception e) { - System.out.println("Unable to set cross platform look and feel."); - e.printStackTrace(); - System.exit(2); - } - } - LibraryHelper.prepareNativeLibraries(); - NativeGamepad.addListener(GamepadListener.getInstance()); - NativeGamepad.start(); - - // launching with command line arguments - if (args.length > 0) { - parseCommandLine(args); - } else { - createFrame(); - } + parseCommandLine(args); } //TODO: make this less jank private static void parseCommandLine(String[] args) { String host = null; boolean fullscreen = false; + boolean pair = false; int resolution = 720; int refresh = 30; @@ -167,6 +157,8 @@ public class Limelight implements NvConnectionListener { System.out.println("Syntax error: hostname or ip address expected after -host"); System.exit(3); } + } else if (args[i].equals("-pair")) { + pair = true; } else if (args[i].equals("-fs")) { fullscreen = true; } else if (args[i].equals("-720")) { @@ -187,7 +179,7 @@ public class Limelight implements NvConnectionListener { System.exit(5); } - Resolution streamRes = null; + Resolution streamRes = Resolution.RES_720_30; if (resolution == 720 && refresh == 30) { streamRes = Resolution.RES_720_30; @@ -202,8 +194,10 @@ public class Limelight implements NvConnectionListener { StreamConfiguration streamConfig = createConfiguration(streamRes); Limelight limelight = new Limelight(host); - limelight.startUp(streamConfig, fullscreen); - COMMAND_LINE_LAUNCH = true; + if (!pair) + limelight.startUp(streamConfig, fullscreen); + else + limelight.pair(); } @@ -219,7 +213,6 @@ public class Limelight implements NvConnectionListener { @Override public void stageStarting(Stage stage) { System.out.println("Starting "+stage.getName()); - streamFrame.showSpinner(stage); } /** @@ -237,7 +230,6 @@ public class Limelight implements NvConnectionListener { */ @Override public void stageFailed(Stage stage) { - streamFrame.dispose(); conn.stop(); displayError("Connection Error", "Starting " + stage.getName() + " failed"); } @@ -247,7 +239,6 @@ public class Limelight implements NvConnectionListener { */ @Override public void connectionStarted() { - streamFrame.hideSpinner(); } /** @@ -272,7 +263,6 @@ public class Limelight implements NvConnectionListener { new Thread(new Runnable() { @Override public void run() { - streamFrame.dispose(); displayError("Connection Terminated", "The connection failed unexpectedly"); } }).start(); @@ -285,7 +275,7 @@ public class Limelight implements NvConnectionListener { */ @Override public void displayMessage(String message) { - JOptionPane.showMessageDialog(limeFrame, message, "Limelight", JOptionPane.INFORMATION_MESSAGE); + System.out.println(message); } /** @@ -294,7 +284,7 @@ public class Limelight implements NvConnectionListener { * @param message the message to show the user */ public void displayError(String title, String message) { - JOptionPane.showMessageDialog(limeFrame, message, title, JOptionPane.ERROR_MESSAGE); + System.err.println(title + " " + message); } } diff --git a/src/com/limelight/gui/GamepadConfigFrame.java b/src/com/limelight/gui/GamepadConfigFrame.java deleted file mode 100644 index 45a23db..0000000 --- a/src/com/limelight/gui/GamepadConfigFrame.java +++ /dev/null @@ -1,342 +0,0 @@ -package com.limelight.gui; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.GridLayout; -import java.awt.Toolkit; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; -import java.util.HashMap; -import java.util.Map.Entry; - -import javax.swing.Box; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.border.LineBorder; - -import com.limelight.input.Device; -import com.limelight.input.DeviceListener; -import com.limelight.input.gamepad.GamepadComponent; -import com.limelight.input.gamepad.GamepadListener; -import com.limelight.input.gamepad.GamepadMapping; -import com.limelight.input.gamepad.GamepadMapping.Mapping; -import com.limelight.input.gamepad.SourceComponent; -import com.limelight.settings.GamepadSettingsManager; - -/** - * A frame used to configure the gamepad mappings. - * @author Diego Waxemberg - */ -public class GamepadConfigFrame extends JFrame { - private static final long serialVersionUID = 1L; - - private boolean configChanged = false; - - private MappingThread mappingThread; - private GamepadMapping config; - private HashMap componentMap; - - /** - * Constructs a new config frame. The frame is initially invisible and will
- * be made visible after all components are built by calling build() - */ - public GamepadConfigFrame() { - super("Gamepad Settings"); - System.out.println("Creating Settings Frame"); - this.setSize(850, 550); - this.setResizable(false); - this.setAlwaysOnTop(true); - config = GamepadSettingsManager.getSettings(); - - } - - /** - * Builds all components of the config frame and sets the frame visible. - */ - public void build() { - componentMap = new HashMap(); - - GridLayout layout = new GridLayout(GamepadComponent.values().length/2 + 1, 2); - layout.setHgap(60); - layout.setVgap(3); - JPanel mainPanel = new JPanel(layout); - - GamepadComponent[] components = GamepadComponent.values(); - - for (int i = 0; i < components.length; i++) { - - Mapping mapping = config.get(components[i]); - if (mapping == null) { - mapping = config.new Mapping(components[i], false, false); - config.insertMapping(mapping, null); - } - Box componentBox = createComponentBox(mapping); - - mainPanel.add(componentBox); - - } - - Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); - - this.setLocation(dim.width/2-this.getSize().width/2, dim.height/2-this.getSize().height/2); - this.setLayout(new BorderLayout()); - - this.getContentPane().add(mainPanel, "Center"); - this.getContentPane().add(Box.createVerticalStrut(20), "North"); - this.getContentPane().add(Box.createVerticalStrut(20), "South"); - this.getContentPane().add(Box.createHorizontalStrut(20), "East"); - this.getContentPane().add(Box.createHorizontalStrut(20), "West"); - - this.addWindowListener(createWindowListener()); - this.setVisible(true); - } - - /* - * Creates the box that holds the button and checkboxes - */ - private Box createComponentBox(Mapping mapping) { - Box componentBox = Box.createHorizontalBox(); - - JButton mapButton = new JButton(); - JCheckBox invertBox = new GamepadCheckBox("Invert", GamepadCheckBox.Type.INVERT); - JCheckBox triggerBox = new GamepadCheckBox("Trigger", GamepadCheckBox.Type.TRIGGER); - - Dimension buttonSize = new Dimension(110, 24); - mapButton.setMaximumSize(buttonSize); - mapButton.setMinimumSize(buttonSize); - mapButton.setPreferredSize(buttonSize); - mapButton.addActionListener(createMapListener()); - - setButtonText(mapButton, config.getMapping(mapping.padComp)); - - invertBox.setSelected(mapping.invert); - invertBox.addActionListener(createCheckboxListener()); - invertBox.setName(mapping.padComp.name()); - - triggerBox.setSelected(mapping.trigger); - triggerBox.addActionListener(createCheckboxListener()); - triggerBox.setName(mapping.padComp.name()); - triggerBox.setToolTipText("If this component should act as a trigger. (one-way axis)"); - - componentBox.add(Box.createHorizontalStrut(5)); - componentBox.add(mapping.padComp.getLabel()); - componentBox.add(Box.createHorizontalGlue()); - componentBox.add(mapButton); - componentBox.add(invertBox); - componentBox.add(triggerBox); - componentBox.add(Box.createHorizontalStrut(5)); - - componentBox.setBorder(new LineBorder(Color.GRAY, 1, true)); - - componentMap.put(componentBox, mapping); - - return componentBox; - } - - /* - * Creates the listener for the checkbox - */ - private ActionListener createCheckboxListener() { - return new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JCheckBox clicked = (JCheckBox)e.getSource(); - GamepadComponent padComp = GamepadComponent.valueOf(clicked.getName()); - Mapping currentMapping = config.get(padComp); - if (currentMapping == null) { - //this makes more semantic sense to me than using != - clicked.setSelected(!(clicked.isSelected())); - } else { - ((GamepadCheckBox)clicked).setValue(currentMapping, clicked.isSelected()); - configChanged = true; - } - } - }; - } - - /* - * Creates the listener for the window. - * It will save configs on exit and restart controller threads - */ - private WindowListener createWindowListener() { - return new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - if (mappingThread != null && mappingThread.isAlive()) { - mappingThread.interrupt(); - } - if (configChanged) { - updateConfigs(); - } - dispose(); - } - }; - } - - /* - * Creates the listener for the map button - */ - private ActionListener createMapListener() { - return new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Box toMap = (Box)((JButton)e.getSource()).getParent(); - - if (GamepadListener.getInstance().deviceCount() == 0) { - JOptionPane.showMessageDialog(GamepadConfigFrame.this, "No Gamepad Detected"); - return; - } - - map(toMap); - } - }; - } - - /* - * Maps a gamepad component to the clicked component - */ - private void map(final Box toMap) { - if (mappingThread == null || !mappingThread.isAlive()) { - - //a little janky, could probably be fixed up a bit - final JButton buttonPressed = getButton(toMap); - final Mapping mappingToMap = componentMap.get(toMap); - - buttonPressed.setSelected(true); - - buttonPressed.setText("Select Input"); - - mappingThread = new MappingThread(buttonPressed, mappingToMap); - mappingThread.start(); - - GamepadListener.getInstance().addDeviceListener(mappingThread); - } - - } - - /* - * Helper method to get the box component that contains the given a mapping - */ - private Box getBox(Mapping mapping) { - for (Entry entry : componentMap.entrySet()) { - if (entry.getValue() == mapping) { - return entry.getKey(); - } - } - return null; - } - - /* - * Helper method to get the button out of the box component - */ - private JButton getButton(Box componentBox) { - for (java.awt.Component comp : componentBox.getComponents()) { - if (comp instanceof JButton) - return (JButton)comp; - } - return null; - } - - /* - * Writes the current cofig to the configs on disk. - */ - private void updateConfigs() { - GamepadSettingsManager.writeSettings(config); - } - - private void setButtonText(JButton button, SourceComponent comp) { - if (comp == null) { - button.setText(""); - } else { - button.setText(comp.getType().name() + " " + comp.getId()); - } - } - - private class MappingThread extends Thread implements DeviceListener { - private SourceComponent newMapping = null; - private JButton buttonPressed; - private Mapping mappingToMap; - - public MappingThread(JButton buttonPressed, Mapping mappingToMap) { - super("Gamepad Mapping Thread"); - this.buttonPressed = buttonPressed; - this.mappingToMap = mappingToMap; - } - - @Override - public void run() { - - while (newMapping == null) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - setButtonText(buttonPressed, config.getMapping(mappingToMap.padComp)); - GamepadListener.getInstance().removeListener(this); - return; - } - } - - Mapping oldConfig = config.get(newMapping); - if (oldConfig != null) { - getButton(getBox(oldConfig)).setText(""); - } - - config.insertMapping(mappingToMap, newMapping); - - setButtonText(buttonPressed, newMapping); - configChanged = true; - - GamepadListener.getInstance().removeListener(this); - - } - - @Override - public void handleButton(Device device, int buttonId, boolean pressed) { - if (pressed) { - newMapping = new SourceComponent(SourceComponent.Type.BUTTON, buttonId); - } - } - - @Override - public void handleAxis(Device device, int axisId, float newValue, - float lastValue) { - if (Math.abs(newValue) > 0.75) { - newMapping = new SourceComponent(SourceComponent.Type.AXIS, axisId); - } - } - - } - - private static class GamepadCheckBox extends JCheckBox { - private static final long serialVersionUID = 1L; - private enum Type { TRIGGER, INVERT } - private Type type; - - public GamepadCheckBox(String text, Type type) { - super(text); - this.type = type; - } - - public void setValue(Mapping mapping, boolean value) { - switch (type) { - case TRIGGER: - mapping.trigger = value; - break; - case INVERT: - mapping.invert = value; - break; - default: - System.out.println("You did something terrible and should feel terrible."); - System.out.println("Fix it or the checkbox gods will smite you!"); - break; - } - } - } -} diff --git a/src/com/limelight/gui/MainFrame.java b/src/com/limelight/gui/MainFrame.java deleted file mode 100644 index e505410..0000000 --- a/src/com/limelight/gui/MainFrame.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.limelight.gui; - -import java.awt.BorderLayout; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Toolkit; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.IOException; -import java.net.InetAddress; -import java.net.SocketException; -import java.net.UnknownHostException; - -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTextField; - -import org.xmlpull.v1.XmlPullParserException; - -import com.limelight.Limelight; -import com.limelight.binding.PlatformBinding; -import com.limelight.nvstream.NvConnection; -import com.limelight.nvstream.http.NvHTTP; -import com.limelight.settings.PreferencesManager; -import com.limelight.settings.PreferencesManager.Preferences; - -/** - * The main frame of Limelight that allows the user to specify the host and begin the stream. - * @author Diego Waxemberg - *
Cameron Gutman - */ -public class MainFrame { - private JTextField hostField; - private JButton pair; - private JButton stream; - private JFrame limeFrame; - - /** - * Gets the actual JFrame this class creates - * @return the JFrame that is the main frame - */ - public JFrame getLimeFrame() { - return limeFrame; - } - - /** - * Builds all components of the frame, including the frame itself and displays it to the user. - */ - public void build() { - limeFrame = new JFrame("Limelight"); - limeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - Container mainPane = limeFrame.getContentPane(); - - mainPane.setLayout(new BorderLayout()); - - JPanel centerPane = new JPanel(); - centerPane.setLayout(new BoxLayout(centerPane, BoxLayout.Y_AXIS)); - - Preferences prefs = PreferencesManager.getPreferences(); - - hostField = new JTextField(); - hostField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 24)); - hostField.setToolTipText("Enter host name or IP address"); - hostField.setText(prefs.getHost()); - hostField.setSelectionStart(0); - hostField.setSelectionEnd(hostField.getText().length()); - - stream = new JButton("Start Streaming"); - stream.addActionListener(createStreamButtonListener()); - stream.setToolTipText("Start the GeForce stream"); - - pair = new JButton("Pair"); - pair.addActionListener(createPairButtonListener()); - pair.setToolTipText("Send pair request to GeForce PC"); - - Box streamBox = Box.createHorizontalBox(); - streamBox.add(Box.createHorizontalGlue()); - streamBox.add(stream); - streamBox.add(Box.createHorizontalGlue()); - - Box pairBox = Box.createHorizontalBox(); - pairBox.add(Box.createHorizontalGlue()); - pairBox.add(pair); - pairBox.add(Box.createHorizontalGlue()); - - Box hostBox = Box.createHorizontalBox(); - hostBox.add(Box.createHorizontalStrut(20)); - hostBox.add(hostField); - hostBox.add(Box.createHorizontalStrut(20)); - - - Box contentBox = Box.createVerticalBox(); - contentBox.add(Box.createVerticalStrut(20)); - contentBox.add(hostBox); - contentBox.add(Box.createVerticalStrut(5)); - contentBox.add(streamBox); - contentBox.add(Box.createVerticalStrut(10)); - contentBox.add(pairBox); - - contentBox.add(Box.createVerticalGlue()); - - centerPane.add(contentBox); - mainPane.add(centerPane, "Center"); - Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); - - limeFrame.setJMenuBar(createMenuBar()); - limeFrame.getRootPane().setDefaultButton(stream); - limeFrame.setSize(300, 200); - limeFrame.setLocation(dim.width/2-limeFrame.getSize().width/2, dim.height/2-limeFrame.getSize().height/2); - limeFrame.setResizable(false); - limeFrame.setVisible(true); - } - - /* - * Creates the menu bar for the user to go to preferences, mappings, etc. - */ - private JMenuBar createMenuBar() { - JMenuBar menuBar = new JMenuBar(); - JMenu optionsMenu = new JMenu("Options"); - JMenuItem gamepadSettings = new JMenuItem("Gamepad Settings"); - JMenuItem generalSettings = new JMenuItem("Preferences"); - - gamepadSettings.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - new GamepadConfigFrame().build(); - } - }); - - generalSettings.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - new PreferencesFrame().build(); - } - }); - - optionsMenu.add(gamepadSettings); - optionsMenu.add(generalSettings); - - menuBar.add(optionsMenu); - - return menuBar; - } - - /* - * Creates the listener for the stream button- starts the stream process - */ - private ActionListener createStreamButtonListener() { - return new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - String host = hostField.getText(); - Preferences prefs = PreferencesManager.getPreferences(); - if (!host.equals(prefs.getHost())) { - prefs.setHost(host); - PreferencesManager.writePreferences(prefs); - } - Limelight.createInstance(host); - } - }; - } - - /* - * Creates the listener for the pair button- requests a pairing with the specified host - */ - private ActionListener createPairButtonListener() { - return new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - new Thread(new Runnable() { - @Override - public void run() { - String macAddress; - try { - macAddress = NvConnection.getMacAddressString(); - } catch (SocketException e) { - e.printStackTrace(); - return; - } - - if (macAddress == null) { - System.out.println("Couldn't find a MAC address"); - return; - } - - NvHTTP httpConn; - String message; - try { - httpConn = new NvHTTP(InetAddress.getByName(hostField.getText()), - macAddress, PlatformBinding.getDeviceName()); - try { - if (httpConn.getPairState()) { - message = "Already paired"; - } - else { - int session = httpConn.getSessionId(); - if (session == 0) { - message = "Pairing was declined by the target"; - } - else { - message = "Pairing was successful"; - } - } - } catch (IOException e) { - message = e.getMessage(); - } catch (XmlPullParserException e) { - message = e.getMessage(); - } - } catch (UnknownHostException e1) { - message = "Failed to resolve host"; - } - - JOptionPane.showMessageDialog(limeFrame, message, "Limelight", JOptionPane.INFORMATION_MESSAGE); - } - }).start(); - } - }; - } -} diff --git a/src/com/limelight/gui/PreferencesFrame.java b/src/com/limelight/gui/PreferencesFrame.java deleted file mode 100644 index 3244c69..0000000 --- a/src/com/limelight/gui/PreferencesFrame.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.limelight.gui; - -import java.awt.Dimension; -import java.awt.Toolkit; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JFrame; -import javax.swing.JPanel; - -import com.limelight.settings.PreferencesManager; -import com.limelight.settings.PreferencesManager.Preferences; -import com.limelight.settings.PreferencesManager.Preferences.Resolution; - -/** - * A frame that holds user preferences such as streaming resolution - * @author Diego Waxemberg - */ -public class PreferencesFrame extends JFrame { - private static final long serialVersionUID = 1L; - private JComboBox resolution; - private JCheckBox fullscreen; - private Preferences prefs; - - /** - * Construcs a new frame and loads the saved preferences. - *
The frame is not made visible until a call to
build()
is made. - */ - public PreferencesFrame() { - super("Preferences"); - this.setSize(200, 100); - this.setResizable(false); - this.setAlwaysOnTop(true); - prefs = PreferencesManager.getPreferences(); - } - - /** - * Constructs all components of the frame and makes the frame visible to the user. - */ - public void build() { - - JPanel mainPanel = new JPanel(); - mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); - - resolution = new JComboBox(); - for (Resolution res : Resolution.values()) { - resolution.addItem(res); - } - - resolution.setSelectedItem(prefs.getResolution()); - - fullscreen = new JCheckBox("Fullscreen"); - fullscreen.setSelected(prefs.getFullscreen()); - - Box resolutionBox = Box.createHorizontalBox(); - resolutionBox.add(Box.createHorizontalGlue()); - resolutionBox.add(resolution); - resolutionBox.add(Box.createHorizontalGlue()); - - Box fullscreenBox = Box.createHorizontalBox(); - fullscreenBox.add(Box.createHorizontalGlue()); - fullscreenBox.add(fullscreen); - fullscreenBox.add(Box.createHorizontalGlue()); - - mainPanel.add(Box.createVerticalStrut(10)); - mainPanel.add(resolutionBox); - mainPanel.add(Box.createVerticalStrut(5)); - mainPanel.add(fullscreenBox); - mainPanel.add(Box.createVerticalGlue()); - - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - super.windowClosing(e); - if (prefsChanged()) { - writePreferences(); - } - } - }); - - this.getContentPane().add(mainPanel); - - Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); - //center on screen - this.setLocation((int)dim.getWidth()/2-this.getWidth()/2, (int)dim.getHeight()/2-this.getHeight()/2); - - this.setVisible(true); - } - - /* - * Checks if the preferences have changed from the cached preferences. - */ - private boolean prefsChanged() { - return (prefs.getResolution() != resolution.getSelectedItem()) || - (prefs.getFullscreen() != fullscreen.isSelected()); - } - - /* - * Writes the preferences to the disk. - */ - private void writePreferences() { - prefs.setFullscreen(fullscreen.isSelected()); - prefs.setResolution((Resolution)resolution.getSelectedItem()); - PreferencesManager.writePreferences(prefs); - } - -} diff --git a/src/com/limelight/gui/StreamFrame.java b/src/com/limelight/gui/StreamFrame.java deleted file mode 100644 index cc6eae2..0000000 --- a/src/com/limelight/gui/StreamFrame.java +++ /dev/null @@ -1,287 +0,0 @@ -package com.limelight.gui; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Container; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.DisplayMode; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.Point; -import java.awt.Toolkit; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; - -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JProgressBar; - -import com.limelight.Limelight; -import com.limelight.input.KeyboardHandler; -import com.limelight.input.MouseHandler; -import com.limelight.nvstream.NvConnection; -import com.limelight.nvstream.NvConnectionListener.Stage; -import com.limelight.nvstream.StreamConfiguration; - -/** - * The frame to which the video is rendered - * @author Diego Waxemberg - *
Cameron Gutman - * - */ -public class StreamFrame extends JFrame { - private static final long serialVersionUID = 1L; - - private static final double DESIRED_ASPECT_RATIO = 16.0/9.0; - private static final double ALTERNATE_ASPECT_RATIO = 16.0/10.0; - - private KeyboardHandler keyboard; - private MouseHandler mouse; - private JProgressBar spinner; - private JLabel spinnerLabel; - private Cursor noCursor; - private Limelight limelight; - - /** - * Frees the mouse ie. makes it visible and allowed to move outside the frame. - */ - public void freeMouse() { - mouse.free(); - showCursor(); - } - - /** - * Captures the mouse ie. makes it invisible and not allowed to leave the frame - */ - public void captureMouse() { - mouse.capture(); - hideCursor(); - } - - /** - * Builds the components of this frame with the specified configurations. - * @param conn the connection this frame belongs to - * @param streamConfig the configurations for this frame - * @param fullscreen if the frame should be made fullscreen - */ - public void build(Limelight limelight, NvConnection conn, StreamConfiguration streamConfig, boolean fullscreen) { - this.limelight = limelight; - - keyboard = new KeyboardHandler(conn, this); - mouse = new MouseHandler(conn, this); - - this.addKeyListener(keyboard); - this.addMouseListener(mouse); - this.addMouseMotionListener(mouse); - - this.setFocusTraversalKeysEnabled(false); - - this.setSize(streamConfig.getWidth(), streamConfig.getHeight()); - - this.setBackground(Color.BLACK); - this.getContentPane().setBackground(Color.BLACK); - this.getRootPane().setBackground(Color.BLACK); - - this.addWindowListener(createWindowListener()); - - if (fullscreen) { - makeFullScreen(streamConfig); - } - - hideCursor(); - this.setVisible(true); - } - - private ArrayList getDisplayModesByAspectRatio(DisplayMode[] configs, double aspectRatio) { - ArrayList matchingConfigs = new ArrayList(); - - for (DisplayMode config : configs) { - if ((double)config.getWidth()/(double)config.getHeight() == aspectRatio) { - matchingConfigs.add(config); - } - } - - return matchingConfigs; - } - - private DisplayMode getBestDisplay(StreamConfiguration targetConfig, DisplayMode[] configs) { - int targetDisplaySize = targetConfig.getWidth()*targetConfig.getHeight(); - - // Try to match the target aspect ratio - ArrayList aspectMatchingConfigs = getDisplayModesByAspectRatio(configs, DESIRED_ASPECT_RATIO); - if (aspectMatchingConfigs.size() == 0) { - // No matches for the target, so try the alternate - aspectMatchingConfigs = getDisplayModesByAspectRatio(configs, ALTERNATE_ASPECT_RATIO); - if (aspectMatchingConfigs.size() == 0) { - // No matches for either, so just use all of them - aspectMatchingConfigs = new ArrayList(Arrays.asList(configs)); - } - } - - // Sort by display size - Collections.sort(aspectMatchingConfigs, new Comparator() { - @Override - public int compare(DisplayMode o1, DisplayMode o2) { - if (o1.getWidth()*o1.getHeight() > o2.getWidth()*o2.getHeight()) { - return -1; - } else if (o2.getWidth()*o2.getHeight() > o1.getWidth()*o1.getHeight()) { - return 1; - } else { - return 0; - } - } - }); - - // Find the aspect-matching config with the closest matching display size - DisplayMode bestConfig = null; - for (DisplayMode config : aspectMatchingConfigs) { - if (config.getWidth()*config.getHeight() >= targetDisplaySize) { - bestConfig = config; - } - } - - if (bestConfig != null) { - System.out.println("Using full-screen display mode "+bestConfig.getWidth()+"x"+bestConfig.getHeight()+ - " for "+targetConfig.getWidth()+"x"+targetConfig.getHeight()+" stream"); - } - - return bestConfig; - } - - private void makeFullScreen(StreamConfiguration streamConfig) { - GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - if (gd.isFullScreenSupported()) { - this.setUndecorated(true); - gd.setFullScreenWindow(this); - - if (gd.isDisplayChangeSupported()) { - DisplayMode config = getBestDisplay(streamConfig, gd.getDisplayModes()); - if (config != null) { - gd.setDisplayMode(config); - } - } else { - JOptionPane.showMessageDialog( - this, - "Unable to change display resolution. \nThis may not be the correct resolution", - "Display Resolution", - JOptionPane.ERROR_MESSAGE); - } - } else { - JOptionPane.showMessageDialog( - this, - "Your operating system does not support fullscreen.", - "Fullscreen Unsupported", - JOptionPane.ERROR_MESSAGE); - } - } - - /** - * Makes the mouse cursor invisible - */ - public void hideCursor() { - if (noCursor == null) { - // Transparent 16 x 16 pixel cursor image. - BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB); - - // Create a new blank cursor. - noCursor = Toolkit.getDefaultToolkit().createCustomCursor( - cursorImg, new Point(0, 0), "blank cursor"); - } - // Set the blank cursor to the JFrame. - this.setCursor(noCursor); - this.getContentPane().setCursor(noCursor); - } - - /** - * Makes the mouse cursor visible - */ - public void showCursor() { - this.setCursor(Cursor.getDefaultCursor()); - this.getContentPane().setCursor(Cursor.getDefaultCursor()); - } - - /** - * Shows a progress bar with a label underneath that tells the user what - * loading stage the stream is at. - * @param stage the currently loading stage - */ - public void showSpinner(Stage stage) { - - if (spinner == null) { - Container c = this.getContentPane(); - JPanel panel = new JPanel(); - panel.setBackground(Color.BLACK); - panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); - - spinner = new JProgressBar(); - spinner.setIndeterminate(true); - spinner.setMaximumSize(new Dimension(150, 30)); - - spinnerLabel = new JLabel(); - spinnerLabel.setForeground(Color.white); - - Box spinBox = Box.createHorizontalBox(); - spinBox.add(Box.createHorizontalGlue()); - spinBox.add(spinner); - spinBox.add(Box.createHorizontalGlue()); - - Box lblBox = Box.createHorizontalBox(); - lblBox.add(Box.createHorizontalGlue()); - lblBox.add(spinnerLabel); - lblBox.add(Box.createHorizontalGlue()); - - panel.add(Box.createVerticalGlue()); - panel.add(spinBox); - panel.add(Box.createVerticalStrut(10)); - panel.add(lblBox); - panel.add(Box.createVerticalGlue()); - - c.setLayout(new BorderLayout()); - c.add(panel, "Center"); - } - spinnerLabel.setText("Starting " + stage.getName() + "..."); - } - - /** - * Creates the listener for the window. - * It terminates the connection when the window is closed - */ - private WindowListener createWindowListener() { - return new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - close(); - } - }; - } - - /** - * Hides the spinner and the label - */ - public void hideSpinner() { - spinner.setVisible(false); - spinnerLabel.setVisible(false); - } - - /** - * Stops the stream and destroys the frame - */ - public void close() { - limelight.stop(); - dispose(); - if (Limelight.COMMAND_LINE_LAUNCH) { - System.exit(0); - } - } -}