view src/viewer_swing/java/com/glavsoft/viewer/Viewer.java @ 157:7cea8789387b

thread base command listening loop
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 13 Jun 2014 23:12:28 +0900
parents e68dfd1972ac
children 1c9f6acdfeb2
line wrap: on
line source

// Copyright (C) 2010, 2011, 2012, 2013 GlavSoft LLC.
// All rights reserved.
//
//-------------------------------------------------------------------------
// This file is part of the TightVNC software.  Please visit our Web site:
//
//                       http://www.tightvnc.com/
//
// This program 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 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//-------------------------------------------------------------------------
//

package com.glavsoft.viewer;

import com.glavsoft.rfb.protocol.ProtocolSettings;
import com.glavsoft.viewer.cli.Parser;
import com.glavsoft.viewer.mvp.View;
import com.glavsoft.viewer.swing.ConnectionParams;
import com.glavsoft.viewer.swing.ParametersHandler;
import com.glavsoft.viewer.swing.SwingConnectionWorkerFactory;
import com.glavsoft.viewer.swing.SwingViewerWindowFactory;
import com.glavsoft.viewer.swing.gui.ConnectionView;

import javax.swing.*;

import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.logging.*;

import jp.ac.u_ryukyu.treevnc.CreateConnectionParam;
import jp.ac.u_ryukyu.treevnc.MyRfbProto;
import jp.ac.u_ryukyu.treevnc.client.MyRfbProtoClient;

@SuppressWarnings("serial")
public class Viewer extends JApplet implements Runnable, WindowListener , ViewerInterface{

	private Logger logger;
    private int paramsMask;
    private boolean allowAppletInteractiveConnections;

    public final ConnectionParams connectionParams;
    protected String passwordFromParams;
    boolean isSeparateFrame = true;
    protected boolean isApplet = true;
    private final ProtocolSettings settings;
    protected UiSettings uiSettings;
    private volatile boolean isAppletStopped = false;
    private ConnectionPresenter connectionPresenter;
    boolean isTreeVNC = false;
    protected MyRfbProto myRfb;
	private boolean noConnection;

    public static void main(String[] args) {
		Parser parser = new Parser();
		ParametersHandler.completeParserOptions(parser);

		parser.parse(args);
		if (parser.isSet(ParametersHandler.ARG_HELP)) {
			printUsage(parser.optionsUsage());
			System.exit(0);
		}
		Viewer viewer = new Viewer(parser);
		SwingUtilities.invokeLater(viewer);
	}

    public static void printUsage(String additional) {
		System.out.println("Usage: java -jar (progfilename) [hostname [port_number]] [Options]¥n" +
				"    or¥n"+
				" java -jar (progfilename) [Options]¥n" +
				"    or¥n java -jar (progfilename) -help¥n    to view this help¥n¥n" +
				"Where Options are:¥n" + additional +
				"¥nOptions format: -optionName=optionValue. Ex. -host=localhost -port=5900 -viewonly=yes¥n" +
				"Both option name and option value are case insensitive.");
	}

	public Viewer() {
        logger = Logger.getLogger(getClass().getName());
		connectionParams = new ConnectionParams();
		settings = ProtocolSettings.getDefaultSettings();
		uiSettings = new UiSettings();
	}

	private Viewer(Parser parser) {
		this();
        setLoggingLevel(parser.isSet(ParametersHandler.ARG_VERBOSE) ? Level.FINE :
                parser.isSet(ParametersHandler.ARG_VERBOSE_MORE) ? Level.FINER :
                        Level.INFO);

        paramsMask = ParametersHandler.completeSettingsFromCLI(parser, connectionParams, settings, uiSettings);
		passwordFromParams = parser.getValueFor(ParametersHandler.ARG_PASSWORD);
		logger.info("TightVNC Viewer version " + ver());
		isApplet = false;
	}

    private void setLoggingLevel(Level levelToSet) {
        final Logger appLogger = Logger.getLogger("com.glavsoft");
        appLogger.setLevel(levelToSet);
        ConsoleHandler ch = null;
        for (Handler h : appLogger.getHandlers()) {
            if (h instanceof ConsoleHandler) {
                ch = (ConsoleHandler) h;
                break;
            }
        }
        if (null == ch) {
            ch = new ConsoleHandler();
            appLogger.addHandler(ch);
        }
//        ch.setFormatter(new SimpleFormatter());
        ch.setLevel(levelToSet);
    }


    @Override
	public void windowClosing(WindowEvent e) {
		if (e != null && e.getComponent() != null) {
            final Window w = e.getWindow();
            if (w != null) {
                w.setVisible(false);
                w.dispose();
            }
		}
		closeApp();
	}

	/**
	 * Closes App(lication) or stops App(let).
	 */
    public void closeApp() {
        if (connectionPresenter != null) {
            connectionPresenter.cancelConnection();
            logger.info("Connections cancelled.");
        }
        if (isApplet) {
            if ( ! isAppletStopped) {
                logger.severe("Applet is stopped.");
                isAppletStopped  = true;
                repaint();
                stop();
            }
		} else {
			System.exit(0);
		}
	}

	@Override
	public void paint(Graphics g) {
		if ( ! isAppletStopped) {
			super.paint(g);
		} else {
			getContentPane().removeAll();
			g.clearRect(0, 0, getWidth(), getHeight());
			g.drawString("Disconnected", 10, 20);
		}
	}

	@Override
	public void destroy() {
		closeApp();
		super.destroy();
	}

	@Override
	public void init() {
		paramsMask = ParametersHandler.completeSettingsFromApplet(this, connectionParams, settings, uiSettings);
		isSeparateFrame = ParametersHandler.isSeparateFrame;
		passwordFromParams = getParameter(ParametersHandler.ARG_PASSWORD);
		isApplet = true;
        allowAppletInteractiveConnections = ParametersHandler.allowAppletInteractiveConnections;
		repaint();

        try {
            SwingUtilities.invokeAndWait(this);
        } catch (Exception e) {
            logger.severe(e.getMessage());
        }
    }

	@Override
	public void start() {
		super.start();
	}

    private boolean checkJsch() {
        try {
            Class.forName("com.jcraft.jsch.JSch");
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }
    }
    
    public void setNoConnection(boolean c){
    	noConnection = c;
    }
    
    @Override
	public void run() {
        final boolean hasJsch = checkJsch();
        final boolean allowInteractive = allowAppletInteractiveConnections || ! isApplet;
        connectionPresenter = new ConnectionPresenter(hasJsch, allowInteractive);
        connectionPresenter.setNoConnection(noConnection);
        connectionPresenter.addModel("ConnectionParamsModel", connectionParams);
        final ConnectionView connectionView = new ConnectionView(
                Viewer.this, // appWindowListener
                connectionPresenter, hasJsch);
        connectionPresenter.addView(ConnectionPresenter.CONNECTION_VIEW, connectionView);
        if (isApplet) {
            connectionPresenter.addView("AppletStatusStringView", new View() {
                @Override
                public void showView() { /*nop*/ }
                @Override
                public void closeView() { /*nop*/ }
            });
        }
        
        SwingViewerWindowFactory viewerWindowFactory = new SwingViewerWindowFactory(isSeparateFrame, isApplet, this);
        
        connectionPresenter.setConnectionWorkerFactory(
                new SwingConnectionWorkerFactory(connectionView.getFrame(), passwordFromParams, connectionPresenter, viewerWindowFactory, myRfb));
        connectionPresenter.setNeedReconnection(!noConnection);
        connectionPresenter.startConnection(settings, uiSettings, paramsMask);
	}

	@Override
	public void windowOpened(WindowEvent e) { /* nop */ }
	@Override
	public void windowClosed(WindowEvent e) { /* nop */ }
	@Override
	public void windowIconified(WindowEvent e) { /* nop */ }
	@Override
	public void windowDeiconified(WindowEvent e) { /* nop */ }
	@Override
	public void windowActivated(WindowEvent e) { /* nop */ }
	@Override
	public void windowDeactivated(WindowEvent e) { /* nop */ }

	public static String ver() {
		final InputStream mfStream = Viewer.class.getClassLoader().getResourceAsStream(
				"META-INF/MANIFEST.MF");
		if (null == mfStream) {
			System.out.println("No Manifest file found.");
			return "-1";
		}
		try {
			Manifest mf = new Manifest();
			mf.read(mfStream);
			Attributes atts = mf.getMainAttributes();
			return atts.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
		} catch (IOException e) {
			return "-2";
		}
	}


	public void setSocket(Socket soc) { 
		setConnectionParam(soc.getInetAddress().getHostAddress(),soc.getPort());
	}

	public void setOpenPort(int parseInt) {
	}

	public void setTeminationType(boolean b) {
		myRfb.setTerminationType(b);
	}
	
	/**
	 * starter for TreeVNC
	 */
	public void startTreeViewer() {
		MyRfbProtoClient rfb = new MyRfbProtoClient();
		CreateConnectionParam cp = new CreateConnectionParam(rfb);
		cp.runTreeVncCommandListener();
		try {
            cp.findTreeVncRoot();
        } catch (InterruptedException e) {
            System.out.println("cannot find TreeVNC Root "+e.getMessage());
            return;
        }
		isTreeVNC = true;
		myRfb =  rfb;
        settings.setViewOnly(true); // too avoid unnecessary upward traffic
        cp.createConnectionParam(this);
        rfb.setViewer(this);
        cp.getAcceptThread().commandMainLoop();
 	}
	
	/**
	 * start view with specific TreeVNC root
	 */
	public void startTreeViewer(String hostName,boolean cui) {
		MyRfbProtoClient rfb = new MyRfbProtoClient();
		rfb.setCuiVersion(cui);
		CreateConnectionParam cp = new CreateConnectionParam(rfb);
		cp.setHostName(hostName);
		cp.runTreeVncCommandListener();
		cp.createConnectionParam(this);
		isTreeVNC = true;
		rfb.setViewer(this);
		myRfb =  rfb;
        settings.setViewOnly(true); // too avoid unnecessary upward traffic
        cp.getAcceptThread().commandMainLoop();
	}
	
	
	
	
	public void setConnectionParam(String hostName, int port) {
		connectionParams.setHostName(hostName);
		connectionParams.setPortNumber(port);
	}
	
	public void setIsTreeVNC(boolean flag) {
		isTreeVNC = flag;
	}
	
	public MyRfbProto getRfb() {
		return myRfb;
	}

	public boolean getCuiVersion() {
		return myRfb.getCuiVersion();
	}
	public void setCuiVersion(boolean flag) {
		myRfb.setCuiVersion(flag);
	}

    @Override
    public void createRootSelectionPanel() {
    }
}