Mercurial > hg > Members > you > BroadCastTreeVNC
comparison src/treeVnc/CuiMyVncClient.java @ 0:756bfaf731f3
create new repository
author | Yu Taninari <you@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 21 Feb 2012 04:10:12 +0900 |
parents | |
children | 5d72f4c7371d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:756bfaf731f3 |
---|---|
1 package treeVnc; | |
2 | |
3 import java.awt.*; | |
4 import java.awt.event.*; | |
5 import java.io.*; | |
6 import java.net.*; | |
7 import java.nio.ByteBuffer; | |
8 import java.util.Random; | |
9 /* | |
10 import AcceptThread; | |
11 import OptionsNoFrame; | |
12 */ | |
13 | |
14 public class CuiMyVncClient implements InterfaceForViewer { | |
15 | |
16 | |
17 String[] mainArgs; | |
18 String username; | |
19 | |
20 // RfbProto rfb; | |
21 MyRfbProtoClient rfb; | |
22 Thread rfbThread; | |
23 Thread accThread; | |
24 Thread clientThread; | |
25 | |
26 Frame vncFrame; | |
27 Container vncContainer; | |
28 ScrollPane desktopScrollPane; | |
29 GridBagLayout gridbag; | |
30 ButtonPanel buttonPanel; | |
31 Label connStatusLabel; | |
32 CuiVncCanvas vc; | |
33 // OptionsFrame options; | |
34 OptionsNoFrame options; | |
35 ClipboardFrame clipboard; | |
36 RecordingFrame rec; | |
37 | |
38 // Control session recording. | |
39 Object recordingSync; | |
40 String sessionFileName; | |
41 boolean recordingActive; | |
42 boolean recordingStatusChanged; | |
43 String cursorUpdatesDef; | |
44 String eightBitColorsDef; | |
45 | |
46 // Variables read from parameter values. | |
47 String socketFactory; | |
48 String host; | |
49 int port; | |
50 String passwordParam; | |
51 boolean showControls; | |
52 boolean offerRelogin; | |
53 boolean showOfflineDesktop; | |
54 int deferScreenUpdates; | |
55 int deferCursorUpdates; | |
56 int deferUpdateRequests; | |
57 int debugStatsExcludeUpdates; | |
58 int debugStatsMeasureUpdates; | |
59 | |
60 private static final long serialVersionUID = 1L; | |
61 boolean inAnApplet = true; | |
62 boolean inSeparateFrame = false; | |
63 Socket clientSocket = null; | |
64 String parent, treenum; | |
65 private String leaderflag; | |
66 boolean runflag = false; | |
67 boolean first = true; | |
68 | |
69 EchoClient echoValue; | |
70 int echoPort; | |
71 String pHost; | |
72 | |
73 public static void main(String[] argv) { | |
74 CuiMyVncClient v = new CuiMyVncClient(); | |
75 v.echoValue = null; | |
76 v.runClient(argv, v); | |
77 | |
78 } | |
79 | |
80 private void runClient(String[] argv, CuiMyVncClient v) { | |
81 mainArgs = argv; | |
82 | |
83 if (mainArgs.length > 0) | |
84 pHost = mainArgs[0]; | |
85 else | |
86 pHost = "cls080.ie.u-ryukyu.ac.jp"; | |
87 if (mainArgs.length > 1) | |
88 port = Integer.parseInt(mainArgs[1]); | |
89 else | |
90 port = 5999; | |
91 | |
92 v.init(); | |
93 v.start_threads(); | |
94 | |
95 } | |
96 | |
97 | |
98 void checkArgs(String[] argv) { | |
99 if (argv.length > 3) { | |
100 username = argv[3]; | |
101 } else if (argv.length < 2) { | |
102 System.out.println("Please enter argv"); | |
103 System.out.println("hostname(IPaddress) port password"); | |
104 System.exit(0); | |
105 } else { | |
106 username = argv[0]; | |
107 } | |
108 } | |
109 | |
110 // | |
111 // init() | |
112 // | |
113 | |
114 public void init() { | |
115 | |
116 Random rnd = new Random(); | |
117 long ran = rnd.nextInt(5000); | |
118 try { | |
119 Thread.sleep(ran); | |
120 } catch (InterruptedException e) { | |
121 e.printStackTrace(); | |
122 } | |
123 | |
124 readParameters(); | |
125 //readParameters(value); | |
126 | |
127 options = new OptionsNoFrame(this); | |
128 recordingSync = new Object(); | |
129 | |
130 sessionFileName = null; | |
131 recordingActive = false; | |
132 recordingStatusChanged = false; | |
133 cursorUpdatesDef = null; | |
134 eightBitColorsDef = null; | |
135 | |
136 /* | |
137 * try { connectAndAuthenticate(); } catch (NoRouteToHostException e) { | |
138 * fatalError("Network error: no route to server: " + host, e); } catch | |
139 * (UnknownHostException e) { | |
140 * fatalError("Network error: server name unknown: " + host, e); } catch | |
141 * (ConnectException e) { | |
142 * fatalError("Network error: could not connect to server: " + host + | |
143 * ":" + port, e); } catch (Exception e) { } | |
144 */ | |
145 rfbThread = new Thread(this); | |
146 | |
147 } | |
148 | |
149 // | |
150 // run() - executed by the rfbThread to deal with the RFB socket. | |
151 // | |
152 | |
153 public void start_threads() { | |
154 rfbThread.start(); | |
155 } | |
156 | |
157 public void run() { | |
158 | |
159 try { | |
160 if (first) { | |
161 connectAndAuthenticate(); | |
162 accThread = new Thread(new AcceptThread(rfb, 5999)); | |
163 accThread.start(); | |
164 first = false; | |
165 }else { | |
166 reConnectAndAuthenticate(); | |
167 } | |
168 doProtocolInitialisation(); | |
169 | |
170 vc = new CuiVncCanvas(this, 0, 0); | |
171 vc.updateFramebufferSize(); | |
172 | |
173 } catch (IOException e) { | |
174 | |
175 System.out.println("Socket error"); | |
176 // parent no find | |
177 Random rnd = new Random(); | |
178 long ran = rnd.nextInt(5000) + 5000; | |
179 System.out.println(ran); | |
180 // 親がいない場合の処理はここに書く!!!! | |
181 /** | |
182 * this while reconnection | |
183 */ | |
184 | |
185 int counter = 0; | |
186 | |
187 /* | |
188 vncFrame.setVisible(false); | |
189 vncFrame.dispose(); | |
190 */ | |
191 while (true) { | |
192 /** | |
193 * if my last node case reconnectoion stop | |
194 */ | |
195 | |
196 echoValue = new EchoClient(echoValue, this); | |
197 try { | |
198 Thread.sleep(ran); | |
199 } catch (InterruptedException e1) { | |
200 e1.printStackTrace(); | |
201 } | |
202 | |
203 if (counter >= 3) { | |
204 echoValue.openport(); | |
205 echoValue.notfoundParent(); | |
206 } | |
207 | |
208 echoValue.openport(); | |
209 // runflag = echo.losthost(); | |
210 if (echoValue.lostHost()) { | |
211 break; | |
212 } | |
213 counter++; | |
214 } | |
215 // System.exit(0); | |
216 }catch (Exception e) { | |
217 System.out.println(e); | |
218 System.exit(0); | |
219 } | |
220 try{ | |
221 | |
222 processNormalProtocol();// main loop | |
223 | |
224 } catch (NoRouteToHostException e) { | |
225 fatalError("Network error: no route to server: " + host, e); | |
226 } catch (UnknownHostException e) { | |
227 fatalError("Network error: server name unknown: " + host, e); | |
228 } catch (ConnectException e) { | |
229 fatalError("Network error: could not connect to server: " + host | |
230 + ":" + port, e); | |
231 } catch (EOFException e) { | |
232 | |
233 if (leaderflag != null) { | |
234 while (true) { | |
235 echoValue = new EchoClient(echoValue, this); | |
236 echoValue.openport(); | |
237 // runflag = echo.losthost(); | |
238 if (echoValue.lostHost()) { | |
239 break; | |
240 } | |
241 } | |
242 } else { | |
243 if (showOfflineDesktop) { | |
244 e.printStackTrace(); | |
245 System.out | |
246 .println("Network error: remote side closed connection"); | |
247 if (vc != null) { | |
248 vc.enableInput(false); | |
249 } | |
250 if (rfb != null && !rfb.closed()) | |
251 rfb.close(); | |
252 if (showControls && buttonPanel != null) { | |
253 buttonPanel.disableButtonsOnDisconnect(); | |
254 } | |
255 } else { | |
256 fatalError("Network error: remote side closed connection", | |
257 e); | |
258 } | |
259 } | |
260 } catch (IOException e) { | |
261 String str = e.getMessage(); | |
262 if (str != null && str.length() != 0) { | |
263 fatalError("Network Error: " + str, e); | |
264 } else { | |
265 fatalError(e.toString(), e); | |
266 } | |
267 } catch (Exception e) { | |
268 String str = e.getMessage(); | |
269 if (str != null && str.length() != 0) { | |
270 fatalError("Error: " + str, e); | |
271 } else { | |
272 fatalError(e.toString(), e); | |
273 } | |
274 } | |
275 | |
276 } | |
277 | |
278 // | |
279 // Process RFB socket messages. | |
280 // If the rfbThread is being stopped, ignore any exceptions, | |
281 // otherwise rethrow the exception so it can be handled. | |
282 // | |
283 | |
284 void processNormalProtocol() throws Exception { | |
285 try { | |
286 vc.processNormalProtocol();// main loop | |
287 } catch (Exception e) { | |
288 if (rfbThread == null) { | |
289 System.out.println("Ignoring RFB socket exceptions" | |
290 + " because applet is stopping"); | |
291 } else { | |
292 throw e; | |
293 } | |
294 } | |
295 } | |
296 | |
297 // | |
298 // Connect to the RFB server and authenticate the user. | |
299 // | |
300 | |
301 void connectAndAuthenticate() throws Exception { | |
302 showConnectionStatus("Initializing..."); | |
303 | |
304 showConnectionStatus("Connecting to " + host + ", port " + port + "..."); | |
305 | |
306 // rfb = new RfbProto(host, port, this); | |
307 rfb = new MyRfbProtoClient(pHost, port, this); | |
308 | |
309 showConnectionStatus("Connected to server"); | |
310 | |
311 rfb.readVersionMsg(); | |
312 showConnectionStatus("RFB server supports protocol version " | |
313 + rfb.serverMajor + "." + rfb.serverMinor); | |
314 | |
315 rfb.writeVersionMsg(); | |
316 showConnectionStatus("Using RFB protocol version " + rfb.clientMajor | |
317 + "." + rfb.clientMinor); | |
318 | |
319 | |
320 if (rfb.serverMinor == 855) { | |
321 /* | |
322 * if connect to proxy, userEchoPortFlag is true. | |
323 * if connect to client, userEchoPortFlag is false. | |
324 */ | |
325 boolean useEchoPortFlag = rfb.readProxyFlag(); | |
326 | |
327 if (useEchoPortFlag) { | |
328 byte[] b = new byte[4]; | |
329 b = rfb.readEchoPort(); | |
330 echoPort = castByteInt(b); | |
331 | |
332 InetAddress addr = InetAddress.getByName(pHost); | |
333 String h = new String(addr.getHostAddress()); | |
334 | |
335 getParentName(); | |
336 if (!(h.equals(host))) { | |
337 rfb.changeParent(host, port); | |
338 rfb.readVersionMsg(); | |
339 rfb.writeVersionMsg(); | |
340 //boolean flag = rfb.readProxyFlag(); | |
341 } | |
342 } | |
343 } | |
344 | |
345 int secType = rfb.negotiateSecurity(); | |
346 int authType; | |
347 if (secType == RfbProto.SecTypeTight) { | |
348 showConnectionStatus("Enabling TightVNC protocol extensions"); | |
349 rfb.setupTunneling(); | |
350 authType = rfb.negotiateAuthenticationTight(); | |
351 } else { | |
352 authType = secType; | |
353 } | |
354 | |
355 switch (authType) { | |
356 case RfbProto.AuthNone: | |
357 showConnectionStatus("No authentication needed"); | |
358 rfb.authenticateNone(); | |
359 break; | |
360 case RfbProto.AuthVNC: | |
361 showConnectionStatus("Performing standard VNC authentication"); | |
362 if (passwordParam != null) { | |
363 rfb.authenticateVNC(passwordParam); | |
364 } else { | |
365 String pw = askPassword(); | |
366 rfb.authenticateVNC(pw); | |
367 } | |
368 break; | |
369 default: | |
370 throw new Exception("Unknown authentication scheme " + authType); | |
371 } | |
372 } | |
373 | |
374 | |
375 | |
376 void reConnectAndAuthenticate() throws Exception { | |
377 showConnectionStatus("Initializing..."); | |
378 | |
379 showConnectionStatus("Connecting to " + host + ", port " + port + "..."); | |
380 | |
381 rfb.changeParent(host, port); | |
382 | |
383 showConnectionStatus("Connected to server"); | |
384 | |
385 rfb.readVersionMsg(); | |
386 showConnectionStatus("RFB server supports protocol version " | |
387 + rfb.serverMajor + "." + rfb.serverMinor); | |
388 | |
389 rfb.writeVersionMsg(); | |
390 showConnectionStatus("Using RFB protocol version " + rfb.clientMajor | |
391 + "." + rfb.clientMinor); | |
392 | |
393 if (rfb.serverMinor == 855) { | |
394 boolean useEchoPortFlag = rfb.readProxyFlag(); | |
395 if (useEchoPortFlag) { | |
396 byte[] b = new byte[4]; | |
397 b = rfb.readEchoPort(); | |
398 echoPort = castByteInt(b); | |
399 | |
400 InetAddress addr = InetAddress.getByName(pHost); | |
401 String h = new String(addr.getHostAddress()); | |
402 | |
403 getParentName(); | |
404 if (!(h.equals(host))) { | |
405 rfb.changeParent(host, port); | |
406 rfb.readVersionMsg(); | |
407 rfb.writeVersionMsg(); | |
408 //boolean flag = rfb.readProxyFlag(); | |
409 } | |
410 } | |
411 } | |
412 | |
413 int secType = rfb.negotiateSecurity(); | |
414 int authType; | |
415 if (secType == RfbProto.SecTypeTight) { | |
416 showConnectionStatus("Enabling TightVNC protocol extensions"); | |
417 rfb.setupTunneling(); | |
418 authType = rfb.negotiateAuthenticationTight(); | |
419 } else { | |
420 authType = secType; | |
421 } | |
422 | |
423 switch (authType) { | |
424 case RfbProto.AuthNone: | |
425 showConnectionStatus("No authentication needed"); | |
426 rfb.authenticateNone(); | |
427 break; | |
428 case RfbProto.AuthVNC: | |
429 showConnectionStatus("Performing standard VNC authentication"); | |
430 if (passwordParam != null) { | |
431 rfb.authenticateVNC(passwordParam); | |
432 } else { | |
433 String pw = askPassword(); | |
434 rfb.authenticateVNC(pw); | |
435 } | |
436 break; | |
437 default: | |
438 throw new Exception("Unknown authentication scheme " + authType); | |
439 } | |
440 } | |
441 | |
442 // | |
443 // Show a message describing the connection status. | |
444 // To hide the connection status label, use (msg == null). | |
445 // | |
446 | |
447 void showConnectionStatus(String msg) { | |
448 System.out.println(msg); | |
449 } | |
450 | |
451 // | |
452 // Show an authentication panel. | |
453 // | |
454 | |
455 String askPassword() throws Exception { | |
456 /* | |
457 * showConnectionStatus(null); AuthPanel authPanel = new | |
458 * AuthPanel(this); | |
459 * | |
460 * GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = | |
461 * GridBagConstraints.REMAINDER; gbc.anchor = | |
462 * GridBagConstraints.NORTHWEST; gbc.weightx = 1.0; gbc.weighty = 1.0; | |
463 * gbc.ipadx = 100; gbc.ipady = 50; gridbag.setConstraints(authPanel, | |
464 * gbc); vncContainer.add(authPanel); | |
465 * | |
466 * | |
467 * authPanel.moveFocusToDefaultField(); vncContainer.remove(authPanel); | |
468 */ | |
469 showConnectionStatus("ask password..."); | |
470 String pw = mainArgs[2]; | |
471 return pw; | |
472 } | |
473 | |
474 // | |
475 // Do the rest of the protocol initialisation. | |
476 // | |
477 | |
478 void doProtocolInitialisation() throws IOException { | |
479 rfb.writeClientInit(); | |
480 rfb.readServerInit(); | |
481 | |
482 System.out.println("Desktop name is " + rfb.desktopName); | |
483 System.out.println("Desktop size is " + rfb.framebufferWidth + " x " | |
484 + rfb.framebufferHeight); | |
485 | |
486 setEncodings(); | |
487 | |
488 // showConnectionStatus(null); | |
489 } | |
490 | |
491 // | |
492 // Send current encoding list to the RFB server. | |
493 // | |
494 | |
495 int[] encodingsSaved; | |
496 int nEncodingsSaved; | |
497 | |
498 void setEncodings() { | |
499 setEncodings(false); | |
500 } | |
501 | |
502 void autoSelectEncodings() { | |
503 setEncodings(true); | |
504 } | |
505 | |
506 void setEncodings(boolean autoSelectOnly) { | |
507 if (options == null || rfb == null || !rfb.inNormalProtocol) | |
508 return; | |
509 | |
510 int preferredEncoding = options.preferredEncoding; | |
511 if (preferredEncoding == -1) { | |
512 long kbitsPerSecond = rfb.kbitsPerSecond(); | |
513 if (nEncodingsSaved < 1) { | |
514 // Choose Tight or ZRLE encoding for the very first update. | |
515 System.out.println("Using Tight/ZRLE encodings"); | |
516 preferredEncoding = RfbProto.EncodingTight; | |
517 } else if (kbitsPerSecond > 2000 | |
518 && encodingsSaved[0] != RfbProto.EncodingHextile) { | |
519 // Switch to Hextile if the connection speed is above 2Mbps. | |
520 System.out.println("Throughput " + kbitsPerSecond | |
521 + " kbit/s - changing to Hextile encoding"); | |
522 preferredEncoding = RfbProto.EncodingHextile; | |
523 } else if (kbitsPerSecond < 1000 | |
524 && encodingsSaved[0] != RfbProto.EncodingTight) { | |
525 // Switch to Tight/ZRLE if the connection speed is below 1Mbps. | |
526 System.out.println("Throughput " + kbitsPerSecond | |
527 + " kbit/s - changing to Tight/ZRLE encodings"); | |
528 preferredEncoding = RfbProto.EncodingTight; | |
529 } else { | |
530 // Don't change the encoder. | |
531 if (autoSelectOnly) | |
532 return; | |
533 preferredEncoding = encodingsSaved[0]; | |
534 } | |
535 } else { | |
536 // Auto encoder selection is not enabled. | |
537 if (autoSelectOnly) | |
538 return; | |
539 } | |
540 | |
541 int[] encodings = new int[20]; | |
542 int nEncodings = 0; | |
543 | |
544 encodings[nEncodings++] = preferredEncoding; | |
545 if (options.useCopyRect) { | |
546 encodings[nEncodings++] = RfbProto.EncodingCopyRect; | |
547 } | |
548 if (preferredEncoding != RfbProto.EncodingTight) { | |
549 encodings[nEncodings++] = RfbProto.EncodingTight; | |
550 } | |
551 if (preferredEncoding != RfbProto.EncodingZRLE) { | |
552 encodings[nEncodings++] = RfbProto.EncodingZRLE; | |
553 } | |
554 if (preferredEncoding != RfbProto.EncodingHextile) { | |
555 encodings[nEncodings++] = RfbProto.EncodingHextile; | |
556 } | |
557 if (preferredEncoding != RfbProto.EncodingZlib) { | |
558 encodings[nEncodings++] = RfbProto.EncodingZlib; | |
559 } | |
560 /* | |
561 * if (preferredEncoding != RfbProto.EncodingCoRRE) { | |
562 * encodings[nEncodings++] = RfbProto.EncodingCoRRE; } if | |
563 * (preferredEncoding != RfbProto.EncodingRRE) { encodings[nEncodings++] | |
564 * = RfbProto.EncodingRRE; } | |
565 * | |
566 * if (options.compressLevel >= 0 && options.compressLevel <= 9) { | |
567 * encodings[nEncodings++] = RfbProto.EncodingCompressLevel0 + | |
568 * options.compressLevel; } if (options.jpegQuality >= 0 && | |
569 * options.jpegQuality <= 9) { encodings[nEncodings++] = | |
570 * RfbProto.EncodingQualityLevel0 + options.jpegQuality; } if | |
571 * (options.requestCursorUpdates) { encodings[nEncodings++] = | |
572 * RfbProto.EncodingXCursor; encodings[nEncodings++] = | |
573 * RfbProto.EncodingRichCursor; if (!options.ignoreCursorUpdates) | |
574 * encodings[nEncodings++] = RfbProto.EncodingPointerPos; } | |
575 */ | |
576 | |
577 encodings[nEncodings++] = RfbProto.EncodingLastRect; | |
578 encodings[nEncodings++] = RfbProto.EncodingNewFBSize; | |
579 | |
580 boolean encodingsWereChanged = false; | |
581 if (nEncodings != nEncodingsSaved) { | |
582 encodingsWereChanged = true; | |
583 } else { | |
584 for (int i = 0; i < nEncodings; i++) { | |
585 if (encodings[i] != encodingsSaved[i]) { | |
586 encodingsWereChanged = true; | |
587 break; | |
588 } | |
589 } | |
590 } | |
591 | |
592 if (encodingsWereChanged) { | |
593 try { | |
594 // rfb.writeSetEncodings(encodings, nEncodings); | |
595 if (vc != null) { | |
596 vc.softCursorFree(); | |
597 } | |
598 } catch (Exception e) { | |
599 e.printStackTrace(); | |
600 } | |
601 encodingsSaved = encodings; | |
602 nEncodingsSaved = nEncodings; | |
603 } | |
604 } | |
605 | |
606 // | |
607 // setCutText() - send the given cut text to the RFB server. | |
608 // | |
609 | |
610 void setCutText(String text) { | |
611 try { | |
612 if (rfb != null && rfb.inNormalProtocol) { | |
613 rfb.writeClientCutText(text); | |
614 } | |
615 } catch (Exception e) { | |
616 e.printStackTrace(); | |
617 } | |
618 } | |
619 | |
620 // | |
621 // Order change in session recording status. To stop recording, pass | |
622 // null in place of the fname argument. | |
623 // | |
624 | |
625 void setRecordingStatus(String fname) { | |
626 synchronized (recordingSync) { | |
627 sessionFileName = fname; | |
628 recordingStatusChanged = true; | |
629 } | |
630 } | |
631 | |
632 // | |
633 // Start or stop session recording. Returns true if this method call | |
634 // causes recording of a new session. | |
635 // | |
636 | |
637 boolean checkRecordingStatus() throws IOException { | |
638 synchronized (recordingSync) { | |
639 if (recordingStatusChanged) { | |
640 recordingStatusChanged = false; | |
641 if (sessionFileName != null) { | |
642 startRecording(); | |
643 return true; | |
644 } else { | |
645 stopRecording(); | |
646 } | |
647 } | |
648 } | |
649 return false; | |
650 } | |
651 | |
652 // | |
653 // Start session recording. | |
654 // | |
655 | |
656 protected void startRecording() throws IOException { | |
657 synchronized (recordingSync) { | |
658 if (!recordingActive) { | |
659 // Save settings to restore them after recording the session. | |
660 cursorUpdatesDef = options.choices[options.cursorUpdatesIndex] | |
661 .getSelectedItem(); | |
662 eightBitColorsDef = options.choices[options.eightBitColorsIndex] | |
663 .getSelectedItem(); | |
664 // Set options to values suitable for recording. | |
665 options.choices[options.cursorUpdatesIndex].select("Disable"); | |
666 options.choices[options.cursorUpdatesIndex].setEnabled(false); | |
667 options.setEncodings(); | |
668 options.choices[options.eightBitColorsIndex].select("No"); | |
669 options.choices[options.eightBitColorsIndex].setEnabled(false); | |
670 options.setColorFormat(); | |
671 } else { | |
672 rfb.closeSession(); | |
673 } | |
674 | |
675 System.out.println("Recording the session in " + sessionFileName); | |
676 rfb.startSession(sessionFileName); | |
677 recordingActive = true; | |
678 } | |
679 } | |
680 | |
681 // | |
682 // Stop session recording. | |
683 // | |
684 | |
685 protected void stopRecording() throws IOException { | |
686 synchronized (recordingSync) { | |
687 if (recordingActive) { | |
688 // Restore options. | |
689 options.choices[options.cursorUpdatesIndex] | |
690 .select(cursorUpdatesDef); | |
691 options.choices[options.cursorUpdatesIndex].setEnabled(true); | |
692 options.setEncodings(); | |
693 options.choices[options.eightBitColorsIndex] | |
694 .select(eightBitColorsDef); | |
695 options.choices[options.eightBitColorsIndex].setEnabled(true); | |
696 options.setColorFormat(); | |
697 | |
698 rfb.closeSession(); | |
699 System.out.println("Session recording stopped."); | |
700 } | |
701 sessionFileName = null; | |
702 recordingActive = false; | |
703 } | |
704 } | |
705 | |
706 // | |
707 // readParameters() - read parameters from the html source or from the | |
708 // command line. On the command line, the arguments are just a sequence of | |
709 // param_name/param_value pairs where the names and values correspond to | |
710 // those expected in the html applet tag source. | |
711 // | |
712 | |
713 void readParameters() { | |
714 /* | |
715 * host = readParameter("HOST", !inAnApplet); | |
716 * | |
717 * if (host == null) { host = getCodeBase().getHost(); if | |
718 * (host.equals("")) { fatalError("HOST parameter not specified"); } } | |
719 * | |
720 * port = readIntParameter("PORT", 5550); | |
721 */ | |
722 | |
723 // Read "ENCPASSWORD" or "PASSWORD" parameter if specified. | |
724 // readPasswordParameters(); | |
725 | |
726 String str; | |
727 if (inAnApplet) { | |
728 str = readParameter("Open New Window", false); | |
729 if (str != null && str.equalsIgnoreCase("Yes")) | |
730 inSeparateFrame = true; | |
731 } | |
732 | |
733 // "Show Controls" set to "No" disables button panel. | |
734 showControls = true; | |
735 str = readParameter("Show Controls", false); | |
736 if (str != null && str.equalsIgnoreCase("No")) | |
737 showControls = false; | |
738 | |
739 // "Offer Relogin" set to "No" disables "Login again" and "Close | |
740 // window" buttons under error messages in applet mode. | |
741 offerRelogin = true; | |
742 str = readParameter("Offer Relogin", false); | |
743 if (str != null && str.equalsIgnoreCase("No")) | |
744 offerRelogin = false; | |
745 | |
746 // Do we continue showing desktop on remote disconnect? | |
747 showOfflineDesktop = false; | |
748 str = readParameter("Show Offline Desktop", false); | |
749 if (str != null && str.equalsIgnoreCase("Yes")) | |
750 showOfflineDesktop = true; | |
751 | |
752 // Fine tuning options. | |
753 deferScreenUpdates = readIntParameter("Defer screen updates", 20); | |
754 deferCursorUpdates = readIntParameter("Defer cursor updates", 10); | |
755 deferUpdateRequests = readIntParameter("Defer update requests", 0); | |
756 | |
757 // Debugging options. | |
758 debugStatsExcludeUpdates = readIntParameter("DEBUG_XU", 0); | |
759 debugStatsMeasureUpdates = readIntParameter("DEBUG_CU", 0); | |
760 | |
761 // SocketFactory. | |
762 socketFactory = readParameter("SocketFactory", false); | |
763 } | |
764 | |
765 // | |
766 // Read password parameters. If an "ENCPASSWORD" parameter is set, | |
767 // then decrypt the password into the passwordParam string. Otherwise, | |
768 // try to read the "PASSWORD" parameter directly to passwordParam. | |
769 // | |
770 /* | |
771 private void readPasswordParameters() { | |
772 String encPasswordParam = readParameter("ENCPASSWORD", false); | |
773 | |
774 if (encPasswordParam == null) { | |
775 passwordParam = readParameter("PASSWORD", false); | |
776 } else { | |
777 // ENCPASSWORD is hexascii-encoded. Decode. | |
778 byte[] pw = { 0, 0, 0, 0, 0, 0, 0, 0 }; | |
779 int len = encPasswordParam.length() / 2; | |
780 if (len > 8) | |
781 len = 8; | |
782 for (int i = 0; i < len; i++) { | |
783 String hex = encPasswordParam.substring(i * 2, i * 2 + 2); | |
784 Integer x = new Integer(Integer.parseInt(hex, 16)); | |
785 pw[i] = x.byteValue(); | |
786 } | |
787 // Decrypt the password. | |
788 byte[] key = { 23, 82, 107, 6, 35, 78, 88, 7 }; | |
789 DesCipher des = new DesCipher(key); | |
790 des.decrypt(pw, 0, pw, 0); | |
791 passwordParam = new String(pw); | |
792 | |
793 } | |
794 } | |
795 */ | |
796 public String readParameter(String name, boolean required) { | |
797 for (int i = 0; i < mainArgs.length; i += 2) { | |
798 if (mainArgs[i].equalsIgnoreCase(name)) { | |
799 try { | |
800 return mainArgs[i + 1]; | |
801 } catch (Exception e) { | |
802 if (required) { | |
803 fatalError(name + " parameter not specified"); | |
804 } | |
805 return null; | |
806 } | |
807 } | |
808 } | |
809 if (required) { | |
810 fatalError(name + " parameter not specified"); | |
811 } | |
812 return null; | |
813 } | |
814 | |
815 int readIntParameter(String name, int defaultValue) { | |
816 String str = readParameter(name, false); | |
817 int result = defaultValue; | |
818 if (str != null) { | |
819 try { | |
820 result = Integer.parseInt(str); | |
821 } catch (NumberFormatException e) { | |
822 } | |
823 } | |
824 return result; | |
825 } | |
826 | |
827 // | |
828 // disconnect() - close connection to server. | |
829 // | |
830 | |
831 synchronized public void disconnect() { | |
832 System.out.println("Disconnecting"); | |
833 | |
834 if (vc != null) { | |
835 double sec = (System.currentTimeMillis() - vc.statStartTime) / 1000.0; | |
836 double rate = Math.round(vc.statNumUpdates / sec * 100) / 100.0; | |
837 int nRealRects = vc.statNumPixelRects; | |
838 int nPseudoRects = vc.statNumTotalRects - vc.statNumPixelRects; | |
839 System.out.println("Updates received: " + vc.statNumUpdates + " (" | |
840 + nRealRects + " rectangles + " + nPseudoRects | |
841 + " pseudo), " + rate + " updates/sec"); | |
842 int numRectsOther = nRealRects - vc.statNumRectsTight | |
843 - vc.statNumRectsZRLE - vc.statNumRectsHextile | |
844 - vc.statNumRectsRaw - vc.statNumRectsCopy; | |
845 System.out.println("Rectangles:" + " Tight=" + vc.statNumRectsTight | |
846 + "(JPEG=" + vc.statNumRectsTightJPEG + ") ZRLE=" | |
847 + vc.statNumRectsZRLE + " Hextile=" | |
848 + vc.statNumRectsHextile + " Raw=" + vc.statNumRectsRaw | |
849 + " CopyRect=" + vc.statNumRectsCopy + " other=" | |
850 + numRectsOther); | |
851 | |
852 int raw = vc.statNumBytesDecoded; | |
853 int compressed = vc.statNumBytesEncoded; | |
854 if (compressed > 0) { | |
855 double ratio = Math.round((double) raw / compressed * 1000) / 1000.0; | |
856 System.out.println("Pixel data: " + vc.statNumBytesDecoded | |
857 + " bytes, " + vc.statNumBytesEncoded | |
858 + " compressed, ratio " + ratio); | |
859 } | |
860 } | |
861 | |
862 if (rfb != null && !rfb.closed()) | |
863 rfb.close(); | |
864 // options.dispose(); | |
865 clipboard.dispose(); | |
866 if (rec != null) | |
867 rec.dispose(); | |
868 | |
869 System.exit(0); | |
870 | |
871 } | |
872 | |
873 // | |
874 // fatalError() - print out a fatal error message. | |
875 // FIXME: Do we really need two versions of the fatalError() method? | |
876 // | |
877 | |
878 synchronized public void fatalError(String str) { | |
879 System.out.println(str); | |
880 System.exit(1); | |
881 } | |
882 | |
883 synchronized public void fatalError(String str, Exception e) { | |
884 | |
885 if (rfb != null && rfb.closed()) { | |
886 // Not necessary to show error message if the error was caused | |
887 // by I/O problems after the rfb.close() method call. | |
888 System.out.println("RFB thread finished"); | |
889 return; | |
890 } | |
891 | |
892 System.out.println(str); | |
893 e.printStackTrace(); | |
894 | |
895 if (rfb != null) | |
896 rfb.close(); | |
897 | |
898 System.exit(1); | |
899 | |
900 } | |
901 | |
902 // | |
903 // Show message text and optionally "Relogin" and "Close" buttons. | |
904 // | |
905 | |
906 void showMessage(String msg) { | |
907 vncContainer.removeAll(); | |
908 | |
909 Label errLabel = new Label(msg, Label.CENTER); | |
910 errLabel.setFont(new Font("Helvetica", Font.PLAIN, 12)); | |
911 | |
912 if (offerRelogin) { | |
913 /* | |
914 * Panel gridPanel = new Panel(new GridLayout(0, 1)); Panel | |
915 * outerPanel = new Panel(new FlowLayout(FlowLayout.LEFT)); | |
916 * outerPanel.add(gridPanel); vncContainer.setLayout(new | |
917 * FlowLayout(FlowLayout.LEFT, 30, 16)); | |
918 * vncContainer.add(outerPanel); Panel textPanel = new Panel(new | |
919 * FlowLayout(FlowLayout.CENTER)); textPanel.add(errLabel); | |
920 * gridPanel.add(textPanel); gridPanel.add(new ReloginPanel(this)); | |
921 */ | |
922 } else { | |
923 /* | |
924 * vncContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 30)); | |
925 * vncContainer.add(errLabel); | |
926 */ | |
927 } | |
928 | |
929 } | |
930 | |
931 // | |
932 // Stop the applet. | |
933 // Main applet thread will terminate on first exception | |
934 // after seeing that rfbThread has been set to null. | |
935 // | |
936 | |
937 public void stop() { | |
938 System.out.println("Stopping applet"); | |
939 rfbThread = null; | |
940 } | |
941 | |
942 // | |
943 // This method is called before the applet is destroyed. | |
944 // | |
945 | |
946 public void destroy() { | |
947 System.out.println("Destroying applet"); | |
948 | |
949 vncContainer.removeAll(); | |
950 // options.dispose(); | |
951 clipboard.dispose(); | |
952 if (rec != null) | |
953 rec.dispose(); | |
954 if (rfb != null && !rfb.closed()) | |
955 rfb.close(); | |
956 } | |
957 | |
958 // | |
959 // Start/stop receiving mouse events. | |
960 // | |
961 | |
962 public void enableInput(boolean enable) { | |
963 vc.enableInput(enable); | |
964 } | |
965 | |
966 // | |
967 // Close application properly on window close event. | |
968 // | |
969 | |
970 public void windowClosing(WindowEvent evt) { | |
971 System.out.println("Closing window"); | |
972 if (rfb != null) | |
973 disconnect(); | |
974 | |
975 vncContainer.setVisible(false); | |
976 | |
977 } | |
978 | |
979 // | |
980 // Ignore window events we're not interested in. | |
981 // | |
982 | |
983 public void windowActivated(WindowEvent evt) { | |
984 } | |
985 | |
986 public void windowDeactivated(WindowEvent evt) { | |
987 } | |
988 | |
989 public void windowOpened(WindowEvent evt) { | |
990 } | |
991 | |
992 public void windowClosed(WindowEvent evt) { | |
993 } | |
994 | |
995 public void windowIconified(WindowEvent evt) { | |
996 } | |
997 | |
998 public void windowDeiconified(WindowEvent evt) { | |
999 } | |
1000 | |
1001 public void setClientSocket(Socket sock) { | |
1002 clientSocket = sock; | |
1003 } | |
1004 | |
1005 public void start() { | |
1006 | |
1007 } | |
1008 public void close() { | |
1009 rfb.close(); | |
1010 } | |
1011 public void getParentName() { | |
1012 if (echoValue == null) { | |
1013 | |
1014 if (clientSocket == null) { | |
1015 String pHost; | |
1016 if (mainArgs.length > 0) | |
1017 pHost = mainArgs[0]; | |
1018 else | |
1019 pHost = "localhost"; | |
1020 // echo = new EchoClient(pHost, this); | |
1021 echoValue = new EchoClient(pHost, this, echoPort); | |
1022 echoValue.openport(); | |
1023 | |
1024 echoValue = echoValue.requestHostName("1"); | |
1025 } else { | |
1026 echoValue = new EchoClient(); | |
1027 echoValue = echoValue.Interruption(clientSocket); | |
1028 } | |
1029 } | |
1030 | |
1031 // proxyからの返信で接続先を決定する | |
1032 host = echoValue.responseLine; | |
1033 parent = echoValue.parent; | |
1034 if (echoValue.treenum != null) { | |
1035 treenum = echoValue.treenum; | |
1036 } else { | |
1037 treenum = echoValue.treenum; | |
1038 } | |
1039 if (echoValue.leaderflag != null) { | |
1040 leaderflag = echoValue.leaderflag; | |
1041 } else { | |
1042 leaderflag = echoValue.leaderflag; | |
1043 } | |
1044 System.out.println("Parent =" + parent); | |
1045 System.out.println("mynumber =" + treenum); | |
1046 System.out.println("connect host =" + host); | |
1047 System.out.println("leaderflag(boolean) = " + leaderflag); | |
1048 | |
1049 // port = 5999; | |
1050 | |
1051 } | |
1052 public void setEchoValue(EchoClient value) { | |
1053 this.echoValue = value; | |
1054 } | |
1055 | |
1056 | |
1057 int castByteInt(byte[] b) { | |
1058 ByteBuffer bb = ByteBuffer.wrap(b); | |
1059 int echoValue = bb.getInt(); | |
1060 return echoValue; | |
1061 } | |
1062 public Image getScreenImage() { | |
1063 return vc.rawPixelsImage; | |
1064 } | |
1065 | |
1066 public void writeScreenData(byte[] b, String imageFormat) { | |
1067 try{ | |
1068 vc.drawBufferedImage(b); | |
1069 }catch(IOException e){ | |
1070 e.printStackTrace(); | |
1071 } | |
1072 } | |
1073 | |
1074 } |