package com.larocheent.photomouseserver; import java.awt.EventQueue; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Robot; import java.awt.Toolkit; import javax.swing.JButton; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.nio.charset.Charset; import java.util.Hashtable; import javax.swing.JLabel; import java.awt.CardLayout; import java.awt.Component; import java.awt.Color; import javax.swing.JTextArea; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import java.awt.FlowLayout; import javax.swing.JTextField; public class ServerStart { private JFrame frmPhotoMouse; private String line; private StartServer st; private Dimension dim; private JButton btnSavePort, btnQuit; final static String SETTINGS_PANEL = "Settings Panel"; final static String MAIN_PANEL = "Main Panel"; private JTextArea textArea; private JScrollPane sbrText; private JLabel qrLabel; private JPanel panel; private JTextField txtPort; private JLabel lblNewLabel; private SettingsSaver settingsSaver; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { ServerStart window = new ServerStart(); window.frmPhotoMouse.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the application. */ public ServerStart() { initialize(); } /** * Initialize the contents of the frame. */ private void initialize() { settingsSaver = new SettingsSaver(); frmPhotoMouse = new JFrame(); frmPhotoMouse.setResizable(false); frmPhotoMouse.setTitle("Photo Mouse"); frmPhotoMouse.setBounds(100, 100, 338, 306); frmPhotoMouse.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel holder_panel = new JPanel(); frmPhotoMouse.getContentPane().add(holder_panel, BorderLayout.CENTER); holder_panel.setLayout(new CardLayout(0, 0)); @SuppressWarnings("unused") final CardLayout cardLayout; cardLayout = (CardLayout) holder_panel.getLayout(); panel = new JPanel(); panel.setBackground(Color.WHITE); holder_panel.add(panel, MAIN_PANEL); panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5)); JLabel picLabel = new JLabel(new ImageIcon(getClass().getResource("server_logo.png"))); picLabel.setAlignmentX(Component.CENTER_ALIGNMENT); panel.add( picLabel ); qrLabel = new JLabel(new ImageIcon(generateQRCode())); qrLabel.setAlignmentX(Component.CENTER_ALIGNMENT); panel.add( qrLabel ); btnSavePort = new JButton("Save Port"); btnSavePort.setAlignmentX(Component.CENTER_ALIGNMENT); btnSavePort.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent arg0) { st.interrupt(); st = new StartServer(Integer.parseInt(txtPort.getText())); st.start(); settingsSaver.savePortNumber(txtPort.getText()); qrLabel.setIcon(new ImageIcon(generateQRCode())); } }); lblNewLabel = new JLabel("Port:"); panel.add(lblNewLabel); txtPort = new JTextField(); SettingsSaver settingsSaver = new SettingsSaver(); txtPort.setText(settingsSaver.getPortNumber()); txtPort.addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent arg0) { } @Override public void keyReleased(KeyEvent keyEvent) { if(!Character.isDigit(keyEvent.getKeyChar())) { String input = txtPort.getText(); String corrected = input.substring(0, input.length() - 1); txtPort.setText(corrected); } } @Override public void keyTyped(KeyEvent keyEvent) { } }); panel.add(txtPort); txtPort.setColumns(5); panel.add(btnSavePort); btnQuit = new JButton("Quit"); btnQuit.setAlignmentX(Component.CENTER_ALIGNMENT); btnQuit.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent arg0) { System.exit(0); } }); panel.add(btnQuit); textArea = new JTextArea("Click the Start Server button above.", 10, 5); textArea.setEditable(false); textArea.setSize(new Dimension(250, 75)); textArea.setPreferredSize(new Dimension(100, 70)); textArea.setMaximumSize(new Dimension(100, 70)); textArea.setLineWrap(true); sbrText = new JScrollPane(textArea); sbrText.setPreferredSize(new Dimension(275, 75)); sbrText.setMaximumSize(new Dimension(275, 75)); sbrText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); panel.add(sbrText); st = new StartServer(Integer.parseInt(settingsSaver.getPortNumber())); st.start(); textArea.setText("Waiting for a connection...\n"); dim = Toolkit.getDefaultToolkit().getScreenSize(); } private String getNetworkInfo() { InetAddress thisIp = null; try { thisIp = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } return thisIp.getHostAddress(); } private BufferedImage generateQRCode() { Hashtable hintMap = new Hashtable(); hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); QRCodeWriter qrCodeWriter = new QRCodeWriter(); BitMatrix byteMatrix = null; try { SettingsSaver settingsSaver = new SettingsSaver(); byteMatrix = qrCodeWriter.encode("IP:" + getNetworkInfo() + ",PORT:" + settingsSaver.getPortNumber(), BarcodeFormat.QR_CODE, 150, 150, hintMap); } catch (WriterException e) { System.out.println(e); } int matrixWidth = byteMatrix.getWidth(); BufferedImage image = new BufferedImage(matrixWidth, matrixWidth, BufferedImage.TYPE_INT_RGB); image.createGraphics(); Graphics2D graphics = (Graphics2D) image.getGraphics(); graphics.setColor(Color.WHITE); graphics.fillRect(0, 0, matrixWidth, matrixWidth); graphics.setColor(Color.BLACK); for (int i = 0; i < matrixWidth; i++) { for (int j = 0; j < matrixWidth; j++) { if (byteMatrix.get(i, j)) { graphics.fillRect(i, j, 1, 1); } } } return image; } class StartServer extends Thread { protected boolean running = true; private ServerSocket connection = null; private Thread connectionThread = null; private int portNumber; public StartServer(int portNumber) { this.portNumber = portNumber; } public void run() { try{ connection = new ServerSocket(portNumber); connection.setPerformancePreferences(1, 0, 0); textArea.setText("Server started on port: " + portNumber); } catch (IOException e) { System.out.println("Could not listen on port " + portNumber); JOptionPane.showMessageDialog(frmPhotoMouse, "This port is already in use. Please choose a different port number!"); } while(running){ try { connectionThread = new ConnectionThread(connection.accept()); connectionThread.start(); } catch (IOException e) { System.out.println(e); } } connectionThread.interrupt(); try { connection.close(); } catch (IOException e) { System.out.println("Could not close ServerSocket"); } } public void interrupt() { this.running = false; if(connectionThread != null) { connectionThread.interrupt(); } Thread.currentThread().interrupt(); super.interrupt(); } } class ConnectionThread extends Thread { protected Socket clientSocket = null; protected BufferedReader input = null; protected boolean running = true; private Robot computerController = null; private double widthScaleFactor, heightScaleFactor; public ConnectionThread(Socket clientSocket) { this.clientSocket = clientSocket; } public void run() { try { computerController = new Robot(); } catch (AWTException e1) { System.out.println(e1); } try { input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "US-ASCII"), 2028); while (running == true) { line = input.readLine(); handleCommand(line); } } catch (IOException e) { System.out.println(e); } } public void interrupt() { this.running = false; Thread.currentThread().interrupt(); super.interrupt(); } private void handleCommand(String command) { String[] splitString = command.split("="); String commandType = splitString[0]; if(commandType.contentEquals("Move_Mouse")) { handleMoveMouse(splitString[1]); } else if(commandType.contentEquals("Left_Click")) { handleLeftClick(); } else if(commandType.contentEquals("Right_Click")) { handleRightClick(); } else if(commandType.contentEquals("Client_Screen_Size")) { handleScreenSize(splitString[1]); } else if(commandType.contentEquals("Left_Click_Held")) { handleLeftClickHeld(splitString[1]); } else if(commandType.contentEquals("Right_Click_Held")) { handleRightClickHeld(splitString[1]); } else if(commandType.contentEquals("Slider_Position")) { handleSliderChange(splitString[1]); } else if(commandType.contentEquals("Scale_Up")) { handleScaleUp(); } } private void handleScaleUp() { computerController.keyPress(KeyEvent.VK_ALT); computerController.mouseWheel(-1); computerController.keyRelease(KeyEvent.VK_ALT); } private void handleSliderChange(String command) { if(command.contentEquals("100")) { computerController.keyPress(KeyEvent.VK_0); computerController.keyRelease(KeyEvent.VK_0); } else { if(command.length() == 1) { controlOpacity(Integer.parseInt(command.substring(0, 1))); } else if(command.length() == 2) { int firstNumber = Integer.parseInt(command.substring(0, 1)); int secondNumber = Integer.parseInt(command.substring(1, 2)); controlOpacity(firstNumber); controlOpacity(secondNumber); } } } private void controlOpacity(int level) { switch(level) { case 0: computerController.keyPress(KeyEvent.VK_0); computerController.keyRelease(KeyEvent.VK_0); break; case 1: computerController.keyPress(KeyEvent.VK_1); computerController.keyRelease(KeyEvent.VK_1); break; case 2: computerController.keyPress(KeyEvent.VK_2); computerController.keyRelease(KeyEvent.VK_2); break; case 3: computerController.keyPress(KeyEvent.VK_3); computerController.keyRelease(KeyEvent.VK_3); break; case 4: computerController.keyPress(KeyEvent.VK_4); computerController.keyRelease(KeyEvent.VK_4); break; case 5: computerController.keyPress(KeyEvent.VK_5); computerController.keyRelease(KeyEvent.VK_5); break; case 6: computerController.keyPress(KeyEvent.VK_6); computerController.keyRelease(KeyEvent.VK_6); break; case 7: computerController.keyPress(KeyEvent.VK_7); computerController.keyRelease(KeyEvent.VK_7); break; case 8: computerController.keyPress(KeyEvent.VK_8); computerController.keyRelease(KeyEvent.VK_8); break; case 9: computerController.keyPress(KeyEvent.VK_9); computerController.keyRelease(KeyEvent.VK_9); break; } } private void handleLeftClickHeld(String command) { if(command.contentEquals("true")) { computerController.mousePress(InputEvent.BUTTON1_MASK); } if(command.contentEquals("false")) { computerController.mouseRelease(InputEvent.BUTTON1_MASK); } } private void handleRightClickHeld(String command) { if(command.contentEquals("true")) { computerController.mousePress(InputEvent.BUTTON3_MASK); } if(command.contentEquals("false")) { computerController.mouseRelease(InputEvent.BUTTON3_MASK); } } private void handleScreenSize(String command) { String[] incomingSplit = command.split(","); String[] xSplit = incomingSplit[0].split(":"); String[] ySplit = incomingSplit[1].split(":"); System.out.println(xSplit[0]); double padWidth = Double.parseDouble(xSplit[1]); double padHeight = Double.parseDouble(ySplit[1]); double screenWidth = (int)dim.getWidth(); double screenHeight = (int)dim.getHeight(); widthScaleFactor = screenWidth / padWidth; heightScaleFactor = screenHeight / padHeight; System.out.println("Computer Width: " + screenWidth + ", Computer Height: " + screenHeight); System.out.println("Pad Width: " + padWidth + ", Pad Height: " + padHeight); System.out.println("Scaled Width: " + widthScaleFactor + ", Scaled Height: " + heightScaleFactor); } private void handleMoveMouse(String command) { String[] splitString = command.split(","); String[] xPortion = splitString[0].split(":"); String[] yPortion = splitString[1].split(":"); int xCord = Integer.parseInt(xPortion[1]); int yCord = Integer.parseInt(yPortion[1]); double x = xCord * widthScaleFactor; double y = yCord * heightScaleFactor; computerController.mouseMove((int) x, (int) y); } private void handleLeftClick() { computerController.mousePress(InputEvent.BUTTON1_MASK); computerController.mouseRelease(InputEvent.BUTTON1_MASK); } private void handleRightClick() { computerController.mousePress(InputEvent.BUTTON3_MASK); computerController.mouseRelease(InputEvent.BUTTON3_MASK); } } }