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