Mercurial > hg > Applications > TightVNC_orginal
comparison src/main/java/com/glavsoft/rfb/protocol/Protocol.java @ 0:4689cc86d6cb
create TreeViewer2 Repository
author | Yu Taninari <you@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 03 Jul 2012 13:20:49 +0900 |
parents | |
children | e654b2e4de64 472a9bcacb21 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4689cc86d6cb |
---|---|
1 // Copyright (C) 2010, 2011 GlavSoft LLC. | |
2 // All rights reserved. | |
3 // | |
4 //------------------------------------------------------------------------- | |
5 // This file is part of the TightVNC software. Please visit our Web site: | |
6 // | |
7 // http://www.tightvnc.com/ | |
8 // | |
9 // This program is free software; you can redistribute it and/or modify | |
10 // it under the terms of the GNU General Public License as published by | |
11 // the Free Software Foundation; either version 2 of the License, or | |
12 // (at your option) any later version. | |
13 // | |
14 // This program is distributed in the hope that it will be useful, | |
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 // GNU General Public License for more details. | |
18 // | |
19 // You should have received a copy of the GNU General Public License along | |
20 // with this program; if not, write to the Free Software Foundation, Inc., | |
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
22 //------------------------------------------------------------------------- | |
23 // | |
24 | |
25 package com.glavsoft.rfb.protocol; | |
26 | |
27 import com.glavsoft.core.SettingsChangedEvent; | |
28 import com.glavsoft.exceptions.*; | |
29 import com.glavsoft.rfb.*; | |
30 import com.glavsoft.rfb.client.ClientToServerMessage; | |
31 import com.glavsoft.rfb.client.FramebufferUpdateRequestMessage; | |
32 import com.glavsoft.rfb.client.SetEncodingsMessage; | |
33 import com.glavsoft.rfb.client.SetPixelFormatMessage; | |
34 import com.glavsoft.rfb.encoding.PixelFormat; | |
35 import com.glavsoft.rfb.encoding.decoder.DecodersContainer; | |
36 import com.glavsoft.rfb.protocol.state.HandshakeState; | |
37 import com.glavsoft.rfb.protocol.state.ProtocolState; | |
38 import com.glavsoft.transport.Reader; | |
39 import com.glavsoft.transport.Writer; | |
40 | |
41 import java.util.logging.Logger; | |
42 | |
43 public class Protocol implements ProtocolContext, IChangeSettingsListener { | |
44 private ProtocolState state; | |
45 private final Logger logger = Logger.getLogger("com.glavsoft.rfb.protocol"); | |
46 private final IPasswordRetriever passwordRetriever; | |
47 private final ProtocolSettings settings; | |
48 private int fbWidth; | |
49 private int fbHeight; | |
50 private PixelFormat pixelFormat; | |
51 private final Reader reader; | |
52 private final Writer writer; | |
53 private String remoteDesctopName; | |
54 private MessageQueue messageQueue; | |
55 private final DecodersContainer decoders; | |
56 private SenderTask senderTask; | |
57 private ReceiverTask receiverTask; | |
58 private IRfbSessionListener rfbSessionListener; | |
59 private IRepaintController repaintController; | |
60 private PixelFormat serverPixelFormat; | |
61 private Thread senderThread; | |
62 private Thread receiverThread; | |
63 | |
64 public Protocol(Reader reader, Writer writer, | |
65 IPasswordRetriever passwordRetriever, ProtocolSettings settings) { | |
66 this.reader = reader; | |
67 this.writer = writer; | |
68 this.passwordRetriever = passwordRetriever; | |
69 this.settings = settings; | |
70 decoders = new DecodersContainer(); | |
71 decoders.instantiateDecodersWhenNeeded(settings.encodings); | |
72 state = new HandshakeState(this); | |
73 } | |
74 | |
75 @Override | |
76 public void changeStateTo(ProtocolState state) { | |
77 this.state = state; | |
78 } | |
79 | |
80 public void handshake() throws UnsupportedProtocolVersionException, UnsupportedSecurityTypeException, | |
81 AuthenticationFailedException, TransportException, FatalException { | |
82 while (state.next()) { | |
83 continue; | |
84 } | |
85 this.messageQueue = new MessageQueue(); | |
86 } | |
87 | |
88 @Override | |
89 public PixelFormat getPixelFormat() { | |
90 return pixelFormat; | |
91 } | |
92 | |
93 @Override | |
94 public void setPixelFormat(PixelFormat pixelFormat) { | |
95 this.pixelFormat = pixelFormat; | |
96 if (repaintController != null) { | |
97 repaintController.setPixelFormat(pixelFormat); | |
98 } | |
99 } | |
100 | |
101 @Override | |
102 public String getRemoteDesktopName() { | |
103 return remoteDesctopName; | |
104 } | |
105 | |
106 @Override | |
107 public void setRemoteDesktopName(String name) { | |
108 remoteDesctopName = name; | |
109 } | |
110 | |
111 @Override | |
112 public int getFbWidth() { | |
113 return fbWidth; | |
114 } | |
115 | |
116 @Override | |
117 public void setFbWidth(int fbWidth) { | |
118 this.fbWidth = fbWidth; | |
119 } | |
120 | |
121 @Override | |
122 public int getFbHeight() { | |
123 return fbHeight; | |
124 } | |
125 | |
126 @Override | |
127 public void setFbHeight(int fbHeight) { | |
128 this.fbHeight = fbHeight; | |
129 } | |
130 | |
131 @Override | |
132 public IPasswordRetriever getPasswordRetriever() { | |
133 return passwordRetriever; | |
134 } | |
135 | |
136 @Override | |
137 public ProtocolSettings getSettings() { | |
138 return settings; | |
139 } | |
140 | |
141 @Override | |
142 public Logger getLogger() { | |
143 return logger; | |
144 } | |
145 | |
146 @Override | |
147 public Writer getWriter() { | |
148 return writer; | |
149 } | |
150 | |
151 @Override | |
152 public Reader getReader() { | |
153 return reader; | |
154 } | |
155 | |
156 /** | |
157 * Following the server initialisation message it's up to the client to send | |
158 * whichever protocol messages it wants. Typically it will send a | |
159 * SetPixelFormat message and a SetEncodings message, followed by a | |
160 * FramebufferUpdateRequest. From then on the server will send | |
161 * FramebufferUpdate messages in response to the client's | |
162 * FramebufferUpdateRequest messages. The client should send | |
163 * FramebufferUpdateRequest messages with incremental set to true when it has | |
164 * finished processing one FramebufferUpdate and is ready to process another. | |
165 * With a fast client, the rate at which FramebufferUpdateRequests are sent | |
166 * should be regulated to avoid hogging the network. | |
167 */ | |
168 public void startNormalHandling(IRfbSessionListener rfbSessionListener, | |
169 IRepaintController repaintController, ClipboardController clipboardController) { | |
170 this.rfbSessionListener = rfbSessionListener; | |
171 this.repaintController = repaintController; | |
172 // if (settings.getBitsPerPixel() == 0) { | |
173 // settings.setBitsPerPixel(pixelFormat.bitsPerPixel); // the same the server sent when not initialized yet | |
174 // } | |
175 serverPixelFormat = pixelFormat; | |
176 serverPixelFormat.trueColourFlag = 1; // correct flag - we don't support color maps | |
177 setPixelFormat(createPixelFormat(settings)); | |
178 sendMessage(new SetPixelFormatMessage(pixelFormat)); | |
179 logger.fine("sent: "+pixelFormat); | |
180 | |
181 sendSupportedEncodingsMessage(settings); | |
182 settings.addListener(this); // to support pixel format (color depth), and encodings changes | |
183 settings.addListener(repaintController); | |
184 | |
185 sendRefreshMessage(); | |
186 senderTask = new SenderTask(messageQueue, writer, this); | |
187 senderThread = new Thread(senderTask); | |
188 senderThread.start(); | |
189 decoders.resetDecoders(); | |
190 receiverTask = new ReceiverTask( | |
191 reader, repaintController, | |
192 clipboardController, | |
193 decoders, this); | |
194 receiverThread = new Thread(receiverTask); | |
195 receiverThread.start(); | |
196 } | |
197 | |
198 @Override | |
199 public void sendMessage(ClientToServerMessage message) { | |
200 messageQueue.put(message); | |
201 } | |
202 | |
203 private void sendSupportedEncodingsMessage(ProtocolSettings settings) { | |
204 decoders.instantiateDecodersWhenNeeded(settings.encodings); | |
205 SetEncodingsMessage encodingsMessage = new SetEncodingsMessage(settings.encodings); | |
206 sendMessage(encodingsMessage); | |
207 logger.fine("sent: " + encodingsMessage.toString()); | |
208 } | |
209 | |
210 /** | |
211 * create pixel format by bpp | |
212 */ | |
213 private PixelFormat createPixelFormat(ProtocolSettings settings) { | |
214 int serverBigEndianFlag = serverPixelFormat.bigEndianFlag; | |
215 switch (settings.getBitsPerPixel()) { | |
216 case ProtocolSettings.BPP_32: | |
217 return PixelFormat.create32bppPixelFormat(serverBigEndianFlag); | |
218 case ProtocolSettings.BPP_16: | |
219 return PixelFormat.create16bppPixelFormat(serverBigEndianFlag); | |
220 case ProtocolSettings.BPP_8: | |
221 return PixelFormat.create8bppBGRPixelFormat(serverBigEndianFlag); | |
222 case ProtocolSettings.BPP_6: | |
223 return PixelFormat.create6bppPixelFormat(serverBigEndianFlag); | |
224 case ProtocolSettings.BPP_3: | |
225 return PixelFormat.create3bppPixelFormat(serverBigEndianFlag); | |
226 case ProtocolSettings.BPP_SERVER_SETTINGS: | |
227 return serverPixelFormat; | |
228 default: | |
229 // unsupported bpp, use default | |
230 return PixelFormat.create32bppPixelFormat(serverBigEndianFlag); | |
231 } | |
232 } | |
233 | |
234 @Override | |
235 public void settingsChanged(SettingsChangedEvent e) { | |
236 ProtocolSettings settings = (ProtocolSettings) e.getSource(); | |
237 if (settings.isChangedEncodings()) { | |
238 sendSupportedEncodingsMessage(settings); | |
239 } | |
240 if (settings.changedBitsPerPixel() && receiverTask != null) { | |
241 receiverTask.queueUpdatePixelFormat(createPixelFormat(settings)); | |
242 } | |
243 } | |
244 | |
245 @Override | |
246 public void sendRefreshMessage() { | |
247 sendMessage(new FramebufferUpdateRequestMessage(0, 0, fbWidth, fbHeight, false)); | |
248 logger.fine("sent: full FB Refresh"); | |
249 } | |
250 | |
251 @Override | |
252 public void cleanUpSession(String message) { | |
253 cleanUpSession(); | |
254 rfbSessionListener.rfbSessionStopped(message); | |
255 } | |
256 | |
257 public synchronized void cleanUpSession() { | |
258 if (senderTask != null) { senderTask.stopTask(); } | |
259 if (receiverTask != null) { receiverTask.stopTask(); } | |
260 if (senderTask != null) { | |
261 try { | |
262 senderThread.join(1000); | |
263 } catch (InterruptedException e) { | |
264 // nop | |
265 } | |
266 senderTask = null; | |
267 } | |
268 if (receiverTask != null) { | |
269 try { | |
270 receiverThread.join(1000); | |
271 } catch (InterruptedException e) { | |
272 // nop | |
273 } | |
274 receiverTask = null; | |
275 } | |
276 } | |
277 | |
278 } |