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