Mercurial > hg > Applications > tvnjviewer
diff src/main/java/com/glavsoft/rfb/protocol/ProtocolSettings.java @ 0:daa24f8a557b
TightVNC original
author | YU |
---|---|
date | Thu, 11 Sep 2014 07:30:03 +0900 |
parents | |
children | e28c17afa0e9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/com/glavsoft/rfb/protocol/ProtocolSettings.java Thu Sep 11 07:30:03 2014 +0900 @@ -0,0 +1,445 @@ +// 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.rfb.protocol; + +import com.glavsoft.core.SettingsChangedEvent; +import com.glavsoft.rfb.CapabilityContainer; +import com.glavsoft.rfb.IChangeSettingsListener; +import com.glavsoft.rfb.RfbCapabilityInfo; +import com.glavsoft.rfb.encoding.EncodingType; +import com.glavsoft.rfb.protocol.auth.SecurityType; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; + +/** + * Protocol Settings class + */ +public class ProtocolSettings implements Serializable { + private static final long serialVersionUID = 1L; + + private static final EncodingType DEFAULT_PREFERRED_ENCODING = EncodingType.TIGHT; + public static final int DEFAULT_JPEG_QUALITY = 6; + private static final int DEFAULT_COMPRESSION_LEVEL = -6; + + // color depth constants + public static final int COLOR_DEPTH_32 = 32; + public static final int COLOR_DEPTH_24 = 24; + public static final int COLOR_DEPTH_16 = 16; + public static final int COLOR_DEPTH_8 = 8; + public static final int COLOR_DEPTH_6 = 6; + public static final int COLOR_DEPTH_3 = 3; + + public static final int COLOR_DEPTH_SERVER_SETTINGS = 0; + + private static final int DEFAULT_COLOR_DEPTH = COLOR_DEPTH_24; + + public static final int CHANGED_VIEW_ONLY = 1; // 1 << 0; + public static final int CHANGED_ENCODINGS = 1 << 1; + public static final int CHANGED_ALLOW_COPY_RECT = 1 << 2; + public static final int CHANGED_SHOW_REMOTE_CURSOR = 1 << 3; + public static final int CHANGED_MOUSE_CURSOR_TRACK = 1 << 4; + public static final int CHANGED_COMPRESSION_LEVEL = 1 << 5; + public static final int CHANGED_JPEG_QUALITY = 1 << 6; + public static final int CHANGED_ALLOW_CLIPBOARD_TRANSFER = 1 << 7; + public static final int CHANGED_CONVERT_TO_ASCII = 1 << 8; + public static final int CHANGED_COLOR_DEPTH = 1 << 9; + public static final int CHANGED_SHARED = 1 << 10; + + private transient int changedSettingsMask; + + private boolean sharedFlag; + private boolean viewOnly; + private EncodingType preferredEncoding; + private boolean allowCopyRect; + private boolean showRemoteCursor; + private LocalPointer mouseCursorTrack; + private int compressionLevel; + private int jpegQuality; + private boolean allowClipboardTransfer; + private boolean convertToAscii; + private int colorDepth; + + public transient LinkedHashSet<EncodingType> encodings; + private transient final List<IChangeSettingsListener> listeners; + + public transient CapabilityContainer + tunnelingCapabilities, + authCapabilities, + serverMessagesCapabilities, + clientMessagesCapabilities, + encodingTypesCapabilities; + private transient String remoteCharsetName; + + public static ProtocolSettings getDefaultSettings() { + ProtocolSettings settings = new ProtocolSettings(); + settings.initKnownAuthCapabilities(settings.authCapabilities); + settings.initKnownEncodingTypesCapabilities(settings.encodingTypesCapabilities); + return settings; + } + + private ProtocolSettings() { + sharedFlag = true; + viewOnly = false; + showRemoteCursor = true; + mouseCursorTrack = LocalPointer.ON; + preferredEncoding = DEFAULT_PREFERRED_ENCODING; + allowCopyRect = true; + compressionLevel = DEFAULT_COMPRESSION_LEVEL; + jpegQuality = DEFAULT_JPEG_QUALITY; + convertToAscii = false; + allowClipboardTransfer = true; + colorDepth = COLOR_DEPTH_SERVER_SETTINGS; + refine(); + + listeners = new LinkedList<IChangeSettingsListener>(); + tunnelingCapabilities = new CapabilityContainer(); + authCapabilities = new CapabilityContainer(); + serverMessagesCapabilities = new CapabilityContainer(); + clientMessagesCapabilities = new CapabilityContainer(); + encodingTypesCapabilities = new CapabilityContainer(); + changedSettingsMask = 0; + } + + public ProtocolSettings(ProtocolSettings s) { + this(); + copyDataFrom(s); + changedSettingsMask = s.changedSettingsMask; + encodings = s.encodings; + } + + public void copyDataFrom(ProtocolSettings s) { + copyDataFrom(s, 0); + } + + public void copyDataFrom(ProtocolSettings s, int mask) { + if (null == s) return; + if ((mask & CHANGED_SHARED) == 0) setSharedFlag(s.sharedFlag); + if ((mask & CHANGED_VIEW_ONLY) == 0) setViewOnly(s.viewOnly); + if ((mask & CHANGED_ALLOW_COPY_RECT) == 0) setAllowCopyRect(s.allowCopyRect); + if ((mask & CHANGED_SHOW_REMOTE_CURSOR) == 0) setShowRemoteCursor(s.showRemoteCursor); + if ((mask & CHANGED_ALLOW_CLIPBOARD_TRANSFER) == 0) setAllowClipboardTransfer(s.allowClipboardTransfer); + + if ((mask & CHANGED_MOUSE_CURSOR_TRACK) == 0) setMouseCursorTrack(s.mouseCursorTrack); + if ((mask & CHANGED_COMPRESSION_LEVEL) == 0) setCompressionLevel(s.compressionLevel); + if ((mask & CHANGED_JPEG_QUALITY) == 0) setJpegQuality(s.jpegQuality); + if ((mask & CHANGED_CONVERT_TO_ASCII) == 0) setConvertToAscii(s.convertToAscii); + if ((mask & CHANGED_COLOR_DEPTH) == 0) setColorDepth(s.colorDepth); + if ((mask & CHANGED_ENCODINGS) == 0) setPreferredEncoding(s.preferredEncoding); + } + + private void initKnownAuthCapabilities(CapabilityContainer cc) { + cc.addEnabled(SecurityType.NONE_AUTHENTICATION.getId(), + RfbCapabilityInfo.VENDOR_STANDARD, RfbCapabilityInfo.AUTHENTICATION_NO_AUTH); + cc.addEnabled(SecurityType.VNC_AUTHENTICATION.getId(), + RfbCapabilityInfo.VENDOR_STANDARD, RfbCapabilityInfo.AUTHENTICATION_VNC_AUTH); + //cc.addEnabled( 19, "VENC", "VENCRYPT"); + //cc.addEnabled( 20, "GTKV", "SASL____"); + //cc.addEnabled(129, RfbCapabilityInfo.TIGHT_VNC_VENDOR, "ULGNAUTH"); + //cc.addEnabled(130, RfbCapabilityInfo.TIGHT_VNC_VENDOR, "XTRNAUTH"); + } + + private void initKnownEncodingTypesCapabilities(CapabilityContainer cc) { + cc.add(EncodingType.COPY_RECT.getId(), + RfbCapabilityInfo.VENDOR_STANDARD, RfbCapabilityInfo.ENCODING_COPYRECT); + cc.add(EncodingType.HEXTILE.getId(), + RfbCapabilityInfo.VENDOR_STANDARD, RfbCapabilityInfo.ENCODING_HEXTILE); + cc.add(EncodingType.ZLIB.getId(), + RfbCapabilityInfo.VENDOR_TRIADA, RfbCapabilityInfo.ENCODING_ZLIB); + cc.add(EncodingType.ZRLE.getId(), + RfbCapabilityInfo.VENDOR_TRIADA, RfbCapabilityInfo.ENCODING_ZRLE); + cc.add(EncodingType.RRE.getId(), + RfbCapabilityInfo.VENDOR_STANDARD, RfbCapabilityInfo.ENCODING_RRE); + cc.add(EncodingType.TIGHT.getId(), + RfbCapabilityInfo.VENDOR_TIGHT, RfbCapabilityInfo.ENCODING_TIGHT); + + cc.add(EncodingType.RICH_CURSOR.getId(), + RfbCapabilityInfo.VENDOR_TIGHT, RfbCapabilityInfo.ENCODING_RICH_CURSOR); + cc.add(EncodingType.CURSOR_POS.getId(), + RfbCapabilityInfo.VENDOR_TIGHT, RfbCapabilityInfo.ENCODING_CURSOR_POS); + cc.add(EncodingType.DESKTOP_SIZE.getId(), + RfbCapabilityInfo.VENDOR_TIGHT, RfbCapabilityInfo.ENCODING_DESKTOP_SIZE); + } + + public void addListener(IChangeSettingsListener listener) { + listeners.add(listener); + } + + public byte getSharedFlag() { + return (byte) (sharedFlag ? 1 : 0); + } + + public boolean isShared() { + return sharedFlag; + } + + public void setSharedFlag(boolean sharedFlag) { + if (this.sharedFlag != sharedFlag) { + this.sharedFlag = sharedFlag; + changedSettingsMask |= CHANGED_SHARED; + } + } + + public boolean isViewOnly() { + return viewOnly; + } + + public void setViewOnly(boolean viewOnly) { + if (this.viewOnly != viewOnly) { + this.viewOnly = viewOnly; + changedSettingsMask |= CHANGED_VIEW_ONLY; + } + } + + public void enableAllEncodingCaps() { + encodingTypesCapabilities.setAllEnable(true); + + } + + public int getColorDepth() { + return colorDepth; + } + + /** + * Set depth only in 3, 6, 8, 16, 32. When depth is wrong, it resets to {@link #DEFAULT_COLOR_DEPTH} + */ + public void setColorDepth(int depth) { + if (colorDepth != depth) { + changedSettingsMask |= CHANGED_COLOR_DEPTH; + switch (depth) { + case COLOR_DEPTH_32: + colorDepth = COLOR_DEPTH_24; + break; + case COLOR_DEPTH_24: + case COLOR_DEPTH_16: + case COLOR_DEPTH_8: + case COLOR_DEPTH_6: + case COLOR_DEPTH_3: + case COLOR_DEPTH_SERVER_SETTINGS: + colorDepth = depth; + break; + default: + colorDepth = DEFAULT_COLOR_DEPTH; + } + refine(); + } + } + + public void refine() { + LinkedHashSet<EncodingType> encodings = new LinkedHashSet<EncodingType>(); + if (EncodingType.RAW_ENCODING == preferredEncoding) { + // when RAW selected send no ordinary encodings so only default RAW encoding will be enabled + } else { + encodings.add(preferredEncoding); // preferred first + encodings.addAll(EncodingType.ordinaryEncodings); + if (compressionLevel > 0 && compressionLevel < 10) { + encodings.add(EncodingType.byId( + EncodingType.COMPRESS_LEVEL_0.getId() + compressionLevel)); + } + if (jpegQuality > 0 && jpegQuality < 10 && + (colorDepth == COLOR_DEPTH_24 || colorDepth == COLOR_DEPTH_SERVER_SETTINGS)) { + encodings.add(EncodingType.byId( + EncodingType.JPEG_QUALITY_LEVEL_0.getId() + jpegQuality)); + } + if (allowCopyRect) { + encodings.add(EncodingType.COPY_RECT); + } + } + switch(mouseCursorTrack) { + case OFF: + setShowRemoteCursor(false); + break; + case HIDE: + setShowRemoteCursor(false); + encodings.add(EncodingType.RICH_CURSOR); + encodings.add(EncodingType.CURSOR_POS); + break; + case ON: + default: + setShowRemoteCursor(true); + encodings.add(EncodingType.RICH_CURSOR); + encodings.add(EncodingType.CURSOR_POS); + } + encodings.add(EncodingType.DESKTOP_SIZE); + if ( isEncodingsChanged(this.encodings, encodings) || isChangedEncodings()) { + this.encodings = encodings; + changedSettingsMask |= CHANGED_ENCODINGS; + } + } + + private boolean isEncodingsChanged(LinkedHashSet<EncodingType> encodings1, LinkedHashSet<EncodingType> encodings2) { + if (null == encodings1 || encodings1.size() != encodings2.size()) return true; + Iterator<EncodingType> it1 = encodings1.iterator(); + Iterator<EncodingType> it2 = encodings2.iterator(); + while (it1.hasNext()) { + EncodingType v1 = it1.next(); + EncodingType v2 = it2.next(); + if (v1 != v2) return true; + } + return false; + } + + public void fireListeners() { + if (null == listeners) return; + final SettingsChangedEvent event = new SettingsChangedEvent(new ProtocolSettings(this)); + changedSettingsMask = 0; + for (IChangeSettingsListener listener : listeners) { + listener.settingsChanged(event); + } + } + + public static boolean isRfbSettingsChangedFired(SettingsChangedEvent event) { + return event.getSource() instanceof ProtocolSettings; + } + + public void setPreferredEncoding(EncodingType preferredEncoding) { + if (this.preferredEncoding != preferredEncoding) { + this.preferredEncoding = preferredEncoding; + changedSettingsMask |= CHANGED_ENCODINGS; + refine(); + } + } + + public EncodingType getPreferredEncoding() { + return preferredEncoding; + } + + public void setAllowCopyRect(boolean allowCopyRect) { + if (this.allowCopyRect != allowCopyRect) { + this.allowCopyRect = allowCopyRect; + changedSettingsMask |= CHANGED_ALLOW_COPY_RECT; + refine(); + } + } + + public boolean isAllowCopyRect() { + return allowCopyRect; + } + + private void setShowRemoteCursor(boolean showRemoteCursor) { + if (this.showRemoteCursor != showRemoteCursor) { + this.showRemoteCursor = showRemoteCursor; + changedSettingsMask |= CHANGED_SHOW_REMOTE_CURSOR; + } + } + + public boolean isShowRemoteCursor() { + return showRemoteCursor; + } + + public void setMouseCursorTrack(LocalPointer mouseCursorTrack) { + if (this.mouseCursorTrack != mouseCursorTrack) { + this.mouseCursorTrack = mouseCursorTrack; + changedSettingsMask |= CHANGED_MOUSE_CURSOR_TRACK; + refine(); + } + } + + public LocalPointer getMouseCursorTrack() { + return mouseCursorTrack; + } + + public void setCompressionLevel(int compressionLevel) { + if (this.compressionLevel != compressionLevel) { + this.compressionLevel = compressionLevel; + changedSettingsMask |= CHANGED_COMPRESSION_LEVEL; + refine(); + } + } + + public int getCompressionLevel() { + return compressionLevel; + } + + public void setJpegQuality(int jpegQuality) { + if (this.jpegQuality != jpegQuality) { + this.jpegQuality = jpegQuality; + changedSettingsMask |= CHANGED_JPEG_QUALITY; + refine(); + } + } + + public int getJpegQuality() { + return jpegQuality; + } + + public void setAllowClipboardTransfer(boolean enable) { + if (this.allowClipboardTransfer != enable) { + this.allowClipboardTransfer = enable; + changedSettingsMask |= CHANGED_ALLOW_CLIPBOARD_TRANSFER; + } + } + + public boolean isAllowClipboardTransfer() { + return allowClipboardTransfer; + } + + public boolean isConvertToAscii() { + return convertToAscii; + } + + public void setConvertToAscii(boolean convertToAscii) { + if (this.convertToAscii != convertToAscii) { + this.convertToAscii = convertToAscii; + changedSettingsMask |= CHANGED_CONVERT_TO_ASCII; + } + } + + public boolean isChangedEncodings() { + return (changedSettingsMask & CHANGED_ENCODINGS) == CHANGED_ENCODINGS; + } + + public boolean isChangedColorDepth() { + return (changedSettingsMask & CHANGED_COLOR_DEPTH) == CHANGED_COLOR_DEPTH; + } + + public void setRemoteCharsetName(String remoteCharsetName) { + this.remoteCharsetName = remoteCharsetName; + } + + public String getRemoteCharsetName() { + return remoteCharsetName; + } + + @Override + public String toString() { + return "ProtocolSettings{" + + "sharedFlag=" + sharedFlag + + ", viewOnly=" + viewOnly + + ", preferredEncoding=" + preferredEncoding + + ", allowCopyRect=" + allowCopyRect + + ", showRemoteCursor=" + showRemoteCursor + + ", mouseCursorTrack=" + mouseCursorTrack + + ", compressionLevel=" + compressionLevel + + ", jpegQuality=" + jpegQuality + + ", allowClipboardTransfer=" + allowClipboardTransfer + + ", convertToAscii=" + convertToAscii + + ", colorDepth=" + colorDepth + + '}'; + } +}