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