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