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