tightvnc-java-1.2.7.orig/0040755000076500007650000000000007571452427014272 5ustar olaluolalutightvnc-java-1.2.7.orig/RecordingFrame.java0100644000076500007650000002012307544154441020012 0ustar olaluolalu// // Copyright (C) 2002 Constantin Kaplinsky. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // Recording frame. It allows to control recording RFB sessions into // FBS (FrameBuffer Stream) files. // import java.io.*; import java.awt.*; import java.awt.event.*; class RecordingFrame extends Frame implements WindowListener, ActionListener { boolean recording; TextField fnameField; Button browseButton; Label statusLabel; Button recordButton, nextButton, closeButton; VncViewer viewer; // // Check if current security manager allows to create a // RecordingFrame object. // public static boolean checkSecurity() { SecurityManager security = System.getSecurityManager(); if (security != null) { try { security.checkPropertyAccess("user.dir"); security.checkPropertyAccess("file.separator"); // Work around (rare) checkPropertyAccess bug System.getProperty("user.dir"); } catch (SecurityException e) { System.out.println("SecurityManager restricts session recording."); return false; } } return true; } // // Constructor. // RecordingFrame(VncViewer v) { super("TightVNC Session Recording"); viewer = v; // Determine initial filename for next saved session. // FIXME: Check SecurityManager. String fname = nextNewFilename(System.getProperty("user.dir") + System.getProperty("file.separator") + "vncsession.fbs"); // Construct new panel with file name field and "Browse" button. Panel fnamePanel = new Panel(); GridBagLayout fnameGridbag = new GridBagLayout(); fnamePanel.setLayout(fnameGridbag); GridBagConstraints fnameConstraints = new GridBagConstraints(); fnameConstraints.gridwidth = GridBagConstraints.RELATIVE; fnameConstraints.fill = GridBagConstraints.BOTH; fnameConstraints.weightx = 4.0; fnameField = new TextField(fname, 64); fnameGridbag.setConstraints(fnameField, fnameConstraints); fnamePanel.add(fnameField); fnameField.addActionListener(this); fnameConstraints.gridwidth = GridBagConstraints.REMAINDER; fnameConstraints.weightx = 1.0; browseButton = new Button("Browse"); fnameGridbag.setConstraints(browseButton, fnameConstraints); fnamePanel.add(browseButton); browseButton.addActionListener(this); // Construct the frame. GridBagLayout gridbag = new GridBagLayout(); setLayout(gridbag); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.BOTH; gbc.weighty = 1.0; gbc.insets = new Insets(10, 0, 0, 0); Label helpLabel = new Label("File name to save next recorded session in:", Label.CENTER); gridbag.setConstraints(helpLabel, gbc); add(helpLabel); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 0.0; gbc.insets = new Insets(0, 0, 0, 0); gridbag.setConstraints(fnamePanel, gbc); add(fnamePanel); gbc.fill = GridBagConstraints.BOTH; gbc.weighty = 1.0; gbc.insets = new Insets(10, 0, 10, 0); statusLabel = new Label("", Label.CENTER); gridbag.setConstraints(statusLabel, gbc); add(statusLabel); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1.0; gbc.weighty = 0.0; gbc.gridwidth = 1; gbc.insets = new Insets(0, 0, 0, 0); recordButton = new Button("Record"); gridbag.setConstraints(recordButton, gbc); add(recordButton); recordButton.addActionListener(this); nextButton = new Button("Next file"); gridbag.setConstraints(nextButton, gbc); add(nextButton); nextButton.addActionListener(this); closeButton = new Button("Close"); gridbag.setConstraints(closeButton, gbc); add(closeButton); closeButton.addActionListener(this); // Set correct text, font and color for the statusLabel. stopRecording(); pack(); addWindowListener(this); } // // If the given string ends with ".NNN" where NNN is a decimal // number, increase this number by one. Otherwise, append ".001" // to the given string. // protected String nextFilename(String fname) { int len = fname.length(); int suffixPos = len; int suffixNum = 1; if (len > 4 && fname.charAt(len - 4) == '.') { try { suffixNum = Integer.parseInt(fname.substring(len - 3, len)) + 1; suffixPos = len - 4; } catch (NumberFormatException e) { } } char[] zeroes = {'0', '0', '0'}; String suffix = String.valueOf(suffixNum); if (suffix.length() < 3) { suffix = new String(zeroes, 0, 3 - suffix.length()) + suffix; } return fname.substring(0, suffixPos) + '.' + suffix; } // // Find next name of a file which does not exist yet. // protected String nextNewFilename(String fname) { String newName = fname; File f; try { do { newName = nextFilename(newName); f = new File(newName); } while (f.exists()); } catch (SecurityException e) { } return newName; } // // Let the user choose a file name showing a FileDialog. // protected boolean browseFile() { File currentFile = new File(fnameField.getText()); FileDialog fd = new FileDialog(this, "Save next session as...", FileDialog.SAVE); fd.setDirectory(currentFile.getParent()); fd.setVisible(true); if (fd.getFile() != null) { String newDir = fd.getDirectory(); String sep = System.getProperty("file.separator"); if (newDir.length() > 0) { if (!sep.equals(newDir.substring(newDir.length() - sep.length()))) newDir += sep; } String newFname = newDir + fd.getFile(); if (newFname.equals(fnameField.getText())) { fnameField.setText(newFname); return true; } } return false; } // // Start recording. // public void startRecording() { statusLabel.setText("Status: Recording..."); statusLabel.setFont(new Font("Helvetica", Font.BOLD, 12)); statusLabel.setForeground(Color.red); recordButton.setLabel("Stop recording"); recording = true; viewer.setRecordingStatus(fnameField.getText()); } // // Stop recording. // public void stopRecording() { statusLabel.setText("Status: Not recording."); statusLabel.setFont(new Font("Helvetica", Font.PLAIN, 12)); statusLabel.setForeground(Color.black); recordButton.setLabel("Record"); recording = false; viewer.setRecordingStatus(null); } // // Close our window properly. // public void windowClosing(WindowEvent evt) { setVisible(false); } // // Ignore window events we're not interested in. // public void windowActivated(WindowEvent evt) {} public void windowDeactivated (WindowEvent evt) {} public void windowOpened(WindowEvent evt) {} public void windowClosed(WindowEvent evt) {} public void windowIconified(WindowEvent evt) {} public void windowDeiconified(WindowEvent evt) {} // // Respond to button presses // public void actionPerformed(ActionEvent evt) { if (evt.getSource() == browseButton) { if (browseFile() && recording) startRecording(); } else if (evt.getSource() == recordButton) { if (!recording) { startRecording(); } else { stopRecording(); fnameField.setText(nextNewFilename(fnameField.getText())); } } else if (evt.getSource() == nextButton) { fnameField.setText(nextNewFilename(fnameField.getText())); if (recording) startRecording(); } else if (evt.getSource() == closeButton) { setVisible(false); } } } tightvnc-java-1.2.7.orig/WhatsNew0100644000076500007650000004720107571452427015756 0ustar olaluolalu+--------------------------------------------------------------------+ | This is a brief summary of changes introduced in each TightVNC | | release. For more details, please see ChangeLog files included | | in TightVNC source and binary archives. | +--------------------------------------------------------------------+ * TightVNC 1.2.7 - Unix and Win32 versions, Java viewer: The most significant problem with local cursor hadling has been solved -- now clients can see remote cursor movements performed on the server or by another client. New PointerPos encoding and cursor shape updates both minimize bandwidth requirements and greatly improve responsiveness of the mouse pointer, while still allow to track correct pointer position in all situations. - Unix and Win32 versions: In all the places where display numbers had to be used, now it's easy to use port numbers as well. The viewers now allow to use new "hostname::port" syntax, in addition to the traditional "hostname:display" format. The same new syntax can be used in the "Add new client" dialog of Win32 server. In the server, now it's equally easy to set display and port numbers. Besides that, HTTP and RFB port numbers can be set individually. - Unix and Win32 versions: In servers, decreased JPEG quality factors for low quality levels. This improves bandwidth usage while the image quality remains satisfactory in most cases. In clients, JPEG compression is now enabled by default, because usually it's a reasonable choice. To prevent viewers from requesting JPEG compression, new -nojpeg option can be used. - Unix and Win32 versions: Improved installer under Windows, better RPMs for Linux. - Win32 version: Major enhancements in layout and functionality of the dialog boxes. - Win32 version: New keyboard handling code has been ported from RealVNC 3.3.6. This should solve all the issues with arrow keys acting as numbers in console windows, and shift+arrows not working under Win2k. - Win32 version: Adopted WinVNC -reinstall option from RealVNC 3.3.5, together with a number of other changes in different places. The viewer now accepts a port number after the -listen command-line option, an improvement from RealVNC 3.3.6. - Win32 version: Eliminated high CPU usage on the server before sending cursor shape updates. - Unix version: Bugfix for Xvnc's -localhost and -interface options that were broken on many systems, thanks to Luke Mewburn. Xvnc -version command-line option is now supported. - Tight encoding is now documented in rfbproto.h files within source archives. - Java viewer: Implemented new buttons "Login again" and "Close window" near the disconnect or error messages in the applet mode, and introduced new "Offer Relogin" parameter to control this improvement. Thanks to Peter Astrand for the initial version of the "Login again" patch. - Java viewer: Support for connections via HTTP proxies using HTTP CONNECT method. This will not work in the applet mode, due to Java security restrictions. - Java viewer: Extra .vnc files have been removed, having just index.vnc should be enough. Also, an example HTML page has been prepared, to simplify installation under a standalone Web server. - Java viewer: Added a MANIFEST to the JAR archive, to allow easy execution of the JAR file, using java -jar command-line option. - Other minor improvements and bugfixes. ---------------------------------------------------------------------- * TightVNC 1.2.6 - Win32 version: In this version, when WinVNC binds to a local TCP port, it does not try to check several times if the port is in use. It just re-uses the port if the display number is not set to "Auto". One visible effect of this change is that the delay between starting up and showing the icon is greatly reduced. - Unix version: Fixed the bug which caused the vncserver script to fail when the XAUTHORITY environment variable was not set. - Unix version: Fixed the bug which prevented the vncpasswd utility from setting correct permissons on the passwd file. - Unix version: Fixed a repeated challenge replay attack vulnerability, bugtraq id 5296. - Unix version: Added files to simplify building of Linux RPMs, thanks to Peter Astrand. - Unix version: Improved scrolling in the full-screen mode, modified patch from Ville Herva. - Minor cleanups. ---------------------------------------------------------------------- * TightVNC 1.2.5 - Win32 version: Fixed a problem in the I/O subsystem that was introduced in TightVNC 1.2.2 and was causing major slowdown in communication with clients. - Win32 version: Enabled remote upgrade in the installation script. Also, the installer will install a copy of the TightVNC Web site, and will create shortcuts to most important documentation pages. - Win32 version: Implemented new feature to specify applet parameters in URL requests being sent to the built-in HTTP server. Added support for new "EnableURLParams" registry setting which can be used to enable this feature. - Win32 version: Added support for the NewFBSize pseudo-encoding allowing to change framebuffer geometry on the fly on server's request. - Win32 version: Included "solution" and "project" files for MS Visual Studio 7, from Andrew van der Stock, applied a set of minor fixes to suppress compilation warnings under MS Visual Studio 7. - Win32 version: The viewer now tries to preserve the size and position of the desktop window after applying new connection options. - Unix version: Implemented new feature to specify applet parameters in URL requests being sent to the built-in HTTP server. Added support for new $PARAMS variable in .vnc HTML templates. - Unix version: Added the possibility to keep users' vnc directories under /tmp, as suggested by Ivan Popov. This mode can be enabled by editing the $vncUserDir variable in the vncserver script. Also, new -t option has been implemented in the vncpasswd utility which allows to change VNC password files under /tmp. - Unix version: Applied Xvnc -viewonly patch from Ehud Karni. - Unix version: Applied Linux/PowerPC Xvnc fix from Peter A. Castro. - Unix version: Bug fixed: Xvnc failed to reset compression level and JPEG image quality on reading lists of encodings supported by clients. - Unix version: Made the viewer handle XCursor encoding operating on the framebuffer instead of setting new cursors directly in X. - Unix version: Applied a number of porting fixes from Ki Networks, Inc. - Java viewer: Added new feature allowing to save RFB sessions in FBS files compatible with rfbproxy. This feature works only if JVM security manager allows access to the local filesystem, which is usually true only when the viewer is used as a standalone application or if the viewer applet is cryptographically signed. New "Record" button will appear in the button panel if this feature is enabled. - Java viewer: Added new "ENCPASSWORD" parameter, modified patch from Peter Astrand. - Java viewer: Applied patch from Peter Astrand to fix problems with Swedish keys and broken JVMs. - Other minor fixes and cleanups. ---------------------------------------------------------------------- * TightVNC 1.2.4 - Win32 version: WinVNC crashes on reporting zero statistics were fixed. This should eliminate crashes when using x2vnc and win2vnc client programs. - Win32 version: a problem with listening viewer was fixed. Initiating multiple non-shared connections could crash the viewer application. - Win32 version: real passwords are never placed into the password text control in the WinVNC Properties dialog any more. This should prevent grabbing plain-text passwords from that text control. - Win32 version: logging on errors was improved to provide better diagnosis for errors, especially for those causing the message "Connection closed" right after authentication. - Win32 version: handling of log files was improved. Now WinVNC should be able to save backup copies of log files under Win95/98/Me. Also, all log files are now written in MS-DOS/Windows text format instead of the Unix one. - Win32 version: a problem with reporting error messages in the listening viewer was fixed. - Win32 version: reporting incorrect statistics in the Tight encoder was fixed. - Win32 version: HTML pages and templates for the built-in HTTP server were improved. - Unix version: applied patch from Ki Networks, Inc. solving build problems on a number of commercial Unix systems, and fixing a number of minor bugs and typos. - Unix version: added a possibility to denote standard input with the "-" file name instead of a real password file name. - Unix version: fixed a bug causing vncpasswd utility work incorrectly when a file name argument was given in the command line. - Unix version: applied patch to solve keyboard focus problems in the full-screen vncviewer, from Peter Astrand. The patch does not seem to solve all the issues, but definitely makes things better. New grabKeyboard resource was added to control full-screen mode behavior. - Java viewer: new "Show Offline Desktop" parameter was added to make the desktop still visible even after the remote side has closed connection. - Java viewer: error messages were made much more meaningful. - Java viewer: keyboard focus problems were fixed. This should prevent opening new windows (e.g. Options or Clipboard) behind the active authenticator or desktop window. - Java viewer: now "R"/"r" keys can be used to request screen updates in view-only mode. - Java viewer: applied patch from Peter Astrand to fix problems with Swedish keys and broken JVMs. - Other minor fixes and cleanups. ---------------------------------------------------------------------- * TightVNC 1.2.3 - Unix and Win32 versions: zlib library was updated to the most recent version (1.1.4) where a potential security issue was fixed. - Unix and Win32 versions: fixed blocking I/O problems in built-in HTTP servers. Older versions had to wait while one client finishes his transaction, only then they served new client connections, thus making easy denial-of-service attacks possible. - Unix and Win32 versions: updated built-in Java viewer, see details below. - Win32 version: Added support for mouse wheel events. Wheel mouse support is fully compatible and interoperable with Unix version where this feature was available for a long time. - Win32 version (WinVNC): The -connect command-line option now accepts a display number after a hostname. - Win32 version: Creating associations for .vnc files in the installer. - Java viewer was GREATLY improved: the code was converted to Java 1.1, painting techniques were re-designed completely (now the viewer should work in MacOS), several new parameters were added, all parameters were documented in the README file. Most important new features include: support for 24-bit colors, JPEG support in Tight encoding, RFB Bell message support, new "Refresh" button, a possibility to operate in a separate scrollable window, dynamic view-only mode. Many more changes were introduces, see the ChangeLog for more information. Please note that new Java viewer class names were changed, e.g. vncviewer.jar file has become VncViewer.jar etc. - Unix version: a number of changes in the vncserver script, e.g. the default color depth is now 24, extra delay after Xvnc startup removed, font path is now configurable in the beginning of the script, and more. - Unix version: zlib library was removed from the core X sources. Instead, both vncviewer and Xvnc now can use either system zlib and JPEG libraries, or ones packaged within TightVNC source archive in the lib/ directory. Unix sources are distributed in two versions: one with these libraries for those who don't have them installed in the system, and another version without libraries, copied directly from CVS, for those who do have zlib and/or JPEG libraries installed. In the former case, build procedure would include additional "make libs" step. System libraries will be linked dynamically, libraries included in the source archive will be linked in statically. - Unix version now includes comprehensive manual pages for vncviewer, vncserver, Xvnc, vncconnect and vncpasswd programs. The vncinstall script in the source distribution now accepts one more parameter allowing to specify where to install manual pages. - Unix version (Xvnc): a number of patches from Red Hat Linux vnc package were incorporated into the TightVNC codebase. This adds support for more architectures including s390 and s390x, adds a possibility to use tcp_wrappers for Xvnc access control. - Unix version (Xvnc): several bugfixes, e.g. applied patch to fix crash in the code dealing with font server; fixed word alignment problem in raw encoder experienced by Sparc users. - Unix version is no more distributed as patches to a standard VNC release. This is because patches cannot handle changes in binary files and handle file removals very inefficiently. - Other minor fixes and cleanups. ---------------------------------------------------------------------- * TightVNC 1.2.2 - Win32 server: long-standing Win9x resource consumption problem has been fixed. Now the server thread does not use blocking I/O, and therefore is always ready to process messages from the VNCHooks DLL. - Win32 server: now built-in HTTP daemon may be enabled and disabled interactively from the Advanced Preferences dialog (this setting is saved in new "EnableHTTPDaemon" registry key). - Win32 server: changes in layout and text of the Advanced Preferences dialog. - Xvnc: Minor bugfix which should prevent potential dereference of a NULL pointer. - Unix viewer: Now viewer window would be raised on beep (bell) event, unless new -noraiseonbeep option is provided in the command line or "raiseOnBeep" resource set to False. - One more packaging option for the Unix source: ready to build archive with Zlib and JPEG libraries inside. - Other minor fixes and cleanups. ---------------------------------------------------------------------- * TightVNC 1.2.1 - Win32 server: added support for reverse connections on ports other than 5500, modified patch from Steve Kann. - Win32 viewer: added support for new command-line options: -noshared and -encoding XXX. - Bugfixes in Win32 viewer: changes in exception handling eliminate Borland C++ compilation problems causing application crashes on repetitive connections, notably in the listen mode. Also, now warning exceptions causing disconnects are reported to user, except for the case when a user has closed the viewer window. - Better packaging in Win32 version: self-installing package is available, vncviewer now shows correct icon image. - Unix vncviewer: Default tunneling command template has been changed, to allow tunneled connections to hosts where only loopback VNC connections are enabled. New -via command-line option provides enhanced tunneling functionality, now one can make vncviewer tunnel connections to a VNC host via third machine acting as a gateway. - Java viewer: Addition of new parameters PASSWORD, "Show Controls", and "View Only", modified patch from Steve Kann. ---------------------------------------------------------------------- * TightVNC 1.2.0 - Tight encoding is now configurable and can operate at different compression levels where low compression levels are very fast in terms of CPU usage. New "-compresslevel N" option implemented in vncviewer to set compression levels for Tight encoding (1 - fast, 9 - best). - Enhanced techniques to split large rectangles in Tight encoder; now it tries to find large solid-color areas and send them in separate rectangles. - Lossy JPEG compression in Tight encoding has been implemented, new "-quality N" vncviewer option should be used to enable this feature (0 - low image quality and best compression, 9 - best image quality). JPEG compression is used only for screen areas that seem to be suitable for JPEG compression (although algorithms to detect such areas are not perfect, of course). - New "XCursor" and "RichCursor" encodings implemented. They are used to transmit cursor shape updates from server to clients ("local cursor" feature requested by many users). Mouse movement no longer causes framebuffer updates to happen, vncviewer processes mouse locally when this feature is active. New -nocursorshape vncviewer option turns this feature off. - A number of recent changes from both TridiaVNC and AT&T's releases merged into the source, now the code is based on version 3.3.3r2 for Unix part, and on 3.3.3r9 for Win32. - Unix vncviewer: When -tunnel option is specified in the command line, special rules are now used to choose preferred encoding. Now viewer does not think that server is running on the same machine when tunneling is on and the preferred encoding is now "tight" with default compression instead of raw. - Xvnc: Rules to set default pixel formats have been changed: now they are RGB565 instead of BGR556 for color depth 16, and RGB888 instead of BGR888 for depth 24. This makes Xvnc compatible with Imlib renderer used in Gnome and also helps to avoid unnecessary pixel format translations in many cases. - Xvnc: X11 modifier mapped to META key is now Mod4 instead of Mod1. New -compatiblekbd option implemented in Xvnc to force META and ALT keys behave the same way as they do in the original AT&T's version. - A number of bugs fixed: viewer crashes after inflate() call, Xvnc CoRRE encoding problems, Xvnc bit-order issues in XCursor and RichCursor encodings, etc. - Java viewer now supports Tight encoding and cursor shape updates. Drawing techniques were changed, settings "Raw pixel drawing: Fast/Reliable" and "CopyRect: Fast/Reliable" removed from the Options panel since they do not make sense in new drawing model. - Other new features, optimizations, fixes and cleanups, see ChangeLog files. ---------------------------------------------------------------------- * VNC Tight Encoding 1.1 - New ``gradient'' filter implemented in servers (it can be disabled in Xvnc with new -lazytight option). The filter preprocess full-color screen areas prior to compression in order to achieve better compression ratios (with the cost of slower compression). Vncviewers of version 1.0 had support for this filter already, but there was small bug causing image distortions in certain cases. So it is recommended to upgrade both servers and viewers. - Stupid bug fixed: extra unused color was included in palettes in many cases; compression ratios used to be worse than they should be. - The algorithm used to split large rectangles into parts has been changed. This change can increase compression ratios in many situations. - Byte-order issues in servers have been (hopefully) fixed. - Performance tuning, code rewrites and cleanups in various places. ---------------------------------------------------------------------- * VNC Tight Encoding 1.0 - Initial release. ---------------------------------------------------------------------- tightvnc-java-1.2.7.orig/Makefile0100644000076500007650000000210307564144030015711 0ustar olaluolalu# # Making the VNC applet. # CP = cp JC = javac JAR = jar ARCHIVE = VncViewer.jar MANIFEST = MANIFEST.MF PAGES = index.vnc INSTALL_DIR = /usr/local/vnc/classes CLASSES = VncViewer.class RfbProto.class AuthPanel.class VncCanvas.class \ OptionsFrame.class ClipboardFrame.class ButtonPanel.class \ DesCipher.class RecordingFrame.class SessionRecorder.class \ SocketFactory.class HTTPConnectSocketFactory.class \ HTTPConnectSocket.class ReloginPanel.class SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \ OptionsFrame.java ClipboardFrame.java ButtonPanel.java \ DesCipher.java RecordingFrame.java SessionRecorder.java \ SocketFactory.java HTTPConnectSocketFactory.java \ HTTPConnectSocket.java ReloginPanel.java all: $(CLASSES) $(ARCHIVE) $(CLASSES): $(SOURCES) $(JC) -O $(SOURCES) $(ARCHIVE): $(CLASSES) $(MANIFEST) $(JAR) cfm $(ARCHIVE) $(MANIFEST) $(CLASSES) install: $(CLASSES) $(ARCHIVE) $(CP) $(CLASSES) $(ARCHIVE) $(PAGES) $(INSTALL_DIR) export:: $(CLASSES) $(ARCHIVE) $(PAGES) @$(ExportJavaClasses) clean:: $(RM) *.class *.jar tightvnc-java-1.2.7.orig/SessionRecorder.java0100644000076500007650000001117507477200226020241 0ustar olaluolalu// // Copyright (C) 2002 Constantin Kaplinsky. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // SessionRecorder is a class to write FBS (FrameBuffer Stream) files. // FBS files are used to save RFB sessions for later playback. // import java.io.*; class SessionRecorder { protected FileOutputStream f; protected DataOutputStream df; protected long startTime, lastTimeOffset; protected byte[] buffer; protected int bufferSize; protected int bufferBytes; public SessionRecorder(String name, int bufsize) throws IOException { f = new FileOutputStream(name); df = new DataOutputStream(f); startTime = System.currentTimeMillis(); lastTimeOffset = 0; bufferSize = bufsize; bufferBytes = 0; buffer = new byte[bufferSize]; } public SessionRecorder(String name) throws IOException { this(name, 65536); } // // Close the file, free resources. // public void close() throws IOException { try { flush(); } catch (IOException e) { } df = null; f.close(); f = null; buffer = null; } // // Write the FBS file header as defined in the rfbproxy utility. // public void writeHeader() throws IOException { df.write("FBS 001.000\n".getBytes()); } // // Write one byte. // public void writeByte(int b) throws IOException { prepareWriting(); buffer[bufferBytes++] = (byte)b; } // // Write 16-bit value, big-endian. // public void writeShortBE(int v) throws IOException { prepareWriting(); buffer[bufferBytes++] = (byte)(v >> 8); buffer[bufferBytes++] = (byte)v; } // // Write 32-bit value, big-endian. // public void writeIntBE(int v) throws IOException { prepareWriting(); buffer[bufferBytes] = (byte)(v >> 24); buffer[bufferBytes + 1] = (byte)(v >> 16); buffer[bufferBytes + 2] = (byte)(v >> 8); buffer[bufferBytes + 3] = (byte)v; bufferBytes += 4; } // // Write 16-bit value, little-endian. // public void writeShortLE(int v) throws IOException { prepareWriting(); buffer[bufferBytes++] = (byte)v; buffer[bufferBytes++] = (byte)(v >> 8); } // // Write 32-bit value, little-endian. // public void writeIntLE(int v) throws IOException { prepareWriting(); buffer[bufferBytes] = (byte)v; buffer[bufferBytes + 1] = (byte)(v >> 8); buffer[bufferBytes + 2] = (byte)(v >> 16); buffer[bufferBytes + 3] = (byte)(v >> 24); bufferBytes += 4; } // // Write byte arrays. // public void write(byte b[], int off, int len) throws IOException { prepareWriting(); while (len > 0) { if (bufferBytes > bufferSize - 4) flush(false); int partLen; if (bufferBytes + len > bufferSize) { partLen = bufferSize - bufferBytes; } else { partLen = len; } System.arraycopy(b, off, buffer, bufferBytes, partLen); bufferBytes += partLen; off += partLen; len -= partLen; } } public void write(byte b[]) throws IOException { write(b, 0, b.length); } // // Flush the output. This method saves buffered data in the // underlying file object adding data sizes and timestamps. If the // updateTimeOffset is set to false, then the current time offset // will not be changed for next write operation. // public void flush(boolean updateTimeOffset) throws IOException { if (bufferBytes > 0) { df.writeInt(bufferBytes); df.write(buffer, 0, (bufferBytes + 3) & 0x7FFFFFFC); df.writeInt((int)lastTimeOffset); bufferBytes = 0; if (updateTimeOffset) lastTimeOffset = -1; } } public void flush() throws IOException { flush(true); } // // Before writing any data, remember time offset and flush the // buffer before it becomes full. // protected void prepareWriting() throws IOException { if (lastTimeOffset == -1) lastTimeOffset = System.currentTimeMillis() - startTime; if (bufferBytes > bufferSize - 4) flush(false); } } tightvnc-java-1.2.7.orig/DesCipher.java0100644000076500007650000004405607165133673017007 0ustar olaluolalu// // This DES class has been extracted from package Acme.Crypto for use in VNC. // The bytebit[] array has been reversed so that the most significant bit // in each byte of the key is ignored, not the least significant. Also the // unnecessary odd parity code has been removed. // // These changes are: // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // DesCipher - the DES encryption method // // The meat of this code is by Dave Zimmerman , and is: // // Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. // // Permission to use, copy, modify, and distribute this software // and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and // without fee is hereby granted, provided that this copyright notice is kept // intact. // // WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY // OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED // TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A // PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE // FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR // DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. // // THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE // CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE // PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT // NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE // SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE // SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE // PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP // SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR // HIGH RISK ACTIVITIES. // // // The rest is: // // Copyright (C) 1996 by Jef Poskanzer . All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. // // Visit the ACME Labs Java page for up-to-date versions of this and other // fine Java utilities: http://www.acme.com/java/ import java.io.*; /// The DES encryption method. //

// This is surprisingly fast, for pure Java. On a SPARC 20, wrapped // in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream, // it does around 7000 bytes/second. //

// Most of this code is by Dave Zimmerman , and is // Copyright (c) 1996 Widget Workshop, Inc. See the source file for details. //

// Fetch the software.
// Fetch the entire Acme package. //

// @see Des3Cipher // @see EncryptedOutputStream // @see EncryptedInputStream public class DesCipher { // Constructor, byte-array key. public DesCipher( byte[] key ) { setKey( key ); } // Key routines. private int[] encryptKeys = new int[32]; private int[] decryptKeys = new int[32]; /// Set the key. public void setKey( byte[] key ) { deskey( key, true, encryptKeys ); deskey( key, false, decryptKeys ); } // Turn an 8-byte key into internal keys. private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL ) { int i, j, l, m, n; int[] pc1m = new int[56]; int[] pcr = new int[56]; int[] kn = new int[32]; for ( j = 0; j < 56; ++j ) { l = pc1[j]; m = l & 07; pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0; } for ( i = 0; i < 16; ++i ) { if ( encrypting ) m = i << 1; else m = (15-i) << 1; n = m+1; kn[m] = kn[n] = 0; for ( j = 0; j < 28; ++j ) { l = j+totrot[i]; if ( l < 28 ) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l-28]; } for ( j=28; j < 56; ++j ) { l = j+totrot[i]; if ( l < 56 ) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l-28]; } for ( j = 0; j < 24; ++j ) { if ( pcr[pc2[j]] != 0 ) kn[m] |= bigbyte[j]; if ( pcr[pc2[j+24]] != 0 ) kn[n] |= bigbyte[j]; } } cookey( kn, KnL ); } private void cookey( int[] raw, int KnL[] ) { int raw0, raw1; int rawi, KnLi; int i; for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i ) { raw0 = raw[rawi++]; raw1 = raw[rawi++]; KnL[KnLi] = (raw0 & 0x00fc0000) << 6; KnL[KnLi] |= (raw0 & 0x00000fc0) << 10; KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10; KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6; ++KnLi; KnL[KnLi] = (raw0 & 0x0003f000) << 12; KnL[KnLi] |= (raw0 & 0x0000003f) << 16; KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4; KnL[KnLi] |= (raw1 & 0x0000003f); ++KnLi; } } // Block encryption routines. private int[] tempInts = new int[2]; /// Encrypt a block of eight bytes. public void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff ) { squashBytesToInts( clearText, clearOff, tempInts, 0, 2 ); des( tempInts, tempInts, encryptKeys ); spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 ); } /// Decrypt a block of eight bytes. public void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff ) { squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 ); des( tempInts, tempInts, decryptKeys ); spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 ); } // The DES function. private void des( int[] inInts, int[] outInts, int[] keys ) { int fval, work, right, leftt; int round; int keysi = 0; leftt = inInts[0]; right = inInts[1]; work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f; right ^= work; leftt ^= (work << 4); work = ((leftt >>> 16) ^ right) & 0x0000ffff; right ^= work; leftt ^= (work << 16); work = ((right >>> 2) ^ leftt) & 0x33333333; leftt ^= work; right ^= (work << 2); work = ((right >>> 8) ^ leftt) & 0x00ff00ff; leftt ^= work; right ^= (work << 8); right = (right << 1) | ((right >>> 31) & 1); work = (leftt ^ right) & 0xaaaaaaaa; leftt ^= work; right ^= work; leftt = (leftt << 1) | ((leftt >>> 31) & 1); for ( round = 0; round < 8; ++round ) { work = (right << 28) | (right >>> 4); work ^= keys[keysi++]; fval = SP7[ work & 0x0000003f ]; fval |= SP5[(work >>> 8) & 0x0000003f ]; fval |= SP3[(work >>> 16) & 0x0000003f ]; fval |= SP1[(work >>> 24) & 0x0000003f ]; work = right ^ keys[keysi++]; fval |= SP8[ work & 0x0000003f ]; fval |= SP6[(work >>> 8) & 0x0000003f ]; fval |= SP4[(work >>> 16) & 0x0000003f ]; fval |= SP2[(work >>> 24) & 0x0000003f ]; leftt ^= fval; work = (leftt << 28) | (leftt >>> 4); work ^= keys[keysi++]; fval = SP7[ work & 0x0000003f ]; fval |= SP5[(work >>> 8) & 0x0000003f ]; fval |= SP3[(work >>> 16) & 0x0000003f ]; fval |= SP1[(work >>> 24) & 0x0000003f ]; work = leftt ^ keys[keysi++]; fval |= SP8[ work & 0x0000003f ]; fval |= SP6[(work >>> 8) & 0x0000003f ]; fval |= SP4[(work >>> 16) & 0x0000003f ]; fval |= SP2[(work >>> 24) & 0x0000003f ]; right ^= fval; } right = (right << 31) | (right >>> 1); work = (leftt ^ right) & 0xaaaaaaaa; leftt ^= work; right ^= work; leftt = (leftt << 31) | (leftt >>> 1); work = ((leftt >>> 8) ^ right) & 0x00ff00ff; right ^= work; leftt ^= (work << 8); work = ((leftt >>> 2) ^ right) & 0x33333333; right ^= work; leftt ^= (work << 2); work = ((right >>> 16) ^ leftt) & 0x0000ffff; leftt ^= work; right ^= (work << 16); work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f; leftt ^= work; right ^= (work << 4); outInts[0] = right; outInts[1] = leftt; } // Tables, permutations, S-boxes, etc. private static byte[] bytebit = { (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x08, (byte)0x10, (byte)0x20, (byte)0x40, (byte)0x80 }; private static int[] bigbyte = { 0x800000, 0x400000, 0x200000, 0x100000, 0x080000, 0x040000, 0x020000, 0x010000, 0x008000, 0x004000, 0x002000, 0x001000, 0x000800, 0x000400, 0x000200, 0x000100, 0x000080, 0x000040, 0x000020, 0x000010, 0x000008, 0x000004, 0x000002, 0x000001 }; private static byte[] pc1 = { (byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8, (byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17, (byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26, (byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35, (byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14, (byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21, (byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28, (byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3 }; private static int[] totrot = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; private static byte[] pc2 = { (byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4, (byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9, (byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7, (byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1, (byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54, (byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47, (byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52, (byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31, }; private static int[] SP1 = { 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004 }; private static int[] SP2 = { 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000 }; private static int[] SP3 = { 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200 }; private static int[] SP4 = { 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080 }; private static int[] SP5 = { 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100 }; private static int[] SP6 = { 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010 }; private static int[] SP7 = { 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002 }; private static int[] SP8 = { 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000 }; // Routines taken from other parts of the Acme utilities. /// Squash bytes down to ints. public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts, int outOff, int intLen ) { for ( int i = 0; i < intLen; ++i ) outInts[outOff + i] = ( ( inBytes[inOff + i * 4 ] & 0xff ) << 24 ) | ( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) | ( ( inBytes[inOff + i * 4 + 2] & 0xff ) << 8 ) | ( inBytes[inOff + i * 4 + 3] & 0xff ); } /// Spread ints into bytes. public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes, int outOff, int intLen ) { for ( int i = 0; i < intLen; ++i ) { outBytes[outOff + i * 4 ] = (byte) ( inInts[inOff + i] >>> 24 ); outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 ); outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 ); outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i]; } } } tightvnc-java-1.2.7.orig/ButtonPanel.java0100644000076500007650000001056607510553327017367 0ustar olaluolalu// // Copyright (C) 2001,2002 HorizonLive.com, Inc. All Rights Reserved. // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // ButtonPanel class implements panel with four buttons in the // VNCViewer desktop window. // import java.awt.*; import java.awt.event.*; import java.io.*; class ButtonPanel extends Panel implements ActionListener { VncViewer viewer; Button disconnectButton; Button optionsButton; Button recordButton; Button clipboardButton; Button ctrlAltDelButton; Button refreshButton; ButtonPanel(VncViewer v) { viewer = v; setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); disconnectButton = new Button("Disconnect"); disconnectButton.setEnabled(false); add(disconnectButton); disconnectButton.addActionListener(this); optionsButton = new Button("Options"); add(optionsButton); optionsButton.addActionListener(this); clipboardButton = new Button("Clipboard"); clipboardButton.setEnabled(false); add(clipboardButton); clipboardButton.addActionListener(this); if (viewer.rec != null) { recordButton = new Button("Record"); add(recordButton); recordButton.addActionListener(this); } ctrlAltDelButton = new Button("Send Ctrl-Alt-Del"); ctrlAltDelButton.setEnabled(false); add(ctrlAltDelButton); ctrlAltDelButton.addActionListener(this); refreshButton = new Button("Refresh"); refreshButton.setEnabled(false); add(refreshButton); refreshButton.addActionListener(this); } // // Enable buttons on successful connection. // public void enableButtons() { disconnectButton.setEnabled(true); clipboardButton.setEnabled(true); refreshButton.setEnabled(true); } // // Disable all buttons on disconnect. // public void disableButtonsOnDisconnect() { remove(disconnectButton); disconnectButton = new Button("Hide desktop"); disconnectButton.setEnabled(true); add(disconnectButton, 0); disconnectButton.addActionListener(this); optionsButton.setEnabled(false); clipboardButton.setEnabled(false); ctrlAltDelButton.setEnabled(false); refreshButton.setEnabled(false); validate(); } // // Enable/disable controls that should not be available in view-only // mode. // public void enableRemoteAccessControls(boolean enable) { ctrlAltDelButton.setEnabled(enable); } // // Event processing. // public void actionPerformed(ActionEvent evt) { viewer.moveFocusToDesktop(); if (evt.getSource() == disconnectButton) { viewer.disconnect(); } else if (evt.getSource() == optionsButton) { viewer.options.setVisible(!viewer.options.isVisible()); } else if (evt.getSource() == recordButton) { viewer.rec.setVisible(!viewer.rec.isVisible()); } else if (evt.getSource() == clipboardButton) { viewer.clipboard.setVisible(!viewer.clipboard.isVisible()); } else if (evt.getSource() == ctrlAltDelButton) { try { final int modifiers = InputEvent.CTRL_MASK | InputEvent.ALT_MASK; KeyEvent ctrlAltDelEvent = new KeyEvent(this, KeyEvent.KEY_PRESSED, 0, modifiers, 127); viewer.rfb.writeKeyEvent(ctrlAltDelEvent); ctrlAltDelEvent = new KeyEvent(this, KeyEvent.KEY_RELEASED, 0, modifiers, 127); viewer.rfb.writeKeyEvent(ctrlAltDelEvent); } catch (IOException e) { e.printStackTrace(); } } else if (evt.getSource() == refreshButton) { try { RfbProto rfb = viewer.rfb; rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, rfb.framebufferHeight, false); } catch (IOException e) { e.printStackTrace(); } } } } tightvnc-java-1.2.7.orig/SocketFactory.java0100644000076500007650000000230007544151275017702 0ustar olaluolalu// // Copyright (C) 2002 HorizonLive.com, Inc. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // SocketFactory.java describes an interface used to substitute the // standard Socket class by its alternative implementations. // import java.applet.*; import java.net.*; import java.io.*; public interface SocketFactory { public Socket createSocket(String host, int port, Applet applet) throws IOException; public Socket createSocket(String host, int port, String[] args) throws IOException; } tightvnc-java-1.2.7.orig/README0100644000076500007650000004423107564510351015144 0ustar olaluolalu TightVNC Java Viewer version 1.2.7 ================================== Copyright (C) 2001,2002 HorizonLive.com, Inc. All Rights Reserved. Copyright (C) 2001,2002 Constantin Kaplinsky. All Rights Reserved. Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. This software is distributed under the GNU General Public Licence as published by the Free Software Foundation. See the file LICENCE.TXT for the conditions under which this software is made available. TightVNC also contains code from other sources. See the Acknowledgements section below, and the individual files for details of the conditions under which they are made available. Compiling from the sources ========================== To compile all the .java files to .class files, simply do: % make all This will also generate a JAR (Java archive) file containing all the classes. Most JVM (Java Virtual Machine) implementations are able to use either a set of .class files, or the JAR archive. Installation ============ There are three basic ways to use TightVNC Java viewer: 1. Running applet as part of TightVNC server installation. Both the Unix and Windows versions of TightVNC servers include small built-in HTTP server which can serve Java viewer to Web clients. This enables easy Web access to the shared desktop without need to install any software on the client computer. Unix and Windows versions of TightVNC servers are different in the way they store the .class and .jar files: the Unix server (Xvnc) is able to serve any set of files present in a particular directory, while the Windows server (WinVNC) has all the .class and .jar files inside the WinVNC executable file. Therefore, for Xvnc, it's enough to copy the files into a correct directory, but for WinVNC, the server binaries should be rebuild if the built-in Java viewer should be updated. To install the Java viewer under Xvnc, copy all the .class files, the .jar file and the .vnc files to an installation directory (e.g. /usr/local/vnc/classes): cp *.class *.jar *.vnc /usr/local/vnc/classes Also, make sure that the vncserver script is configured to point to the installation directory (see the Xvnc manual page for the description of the -httpd command-line option). 2. Running applet hosted on a standalone Web server. Another possibility to use the Java viewer is to install it under a fully-functional HTTP server such as Apache or IIS. Obviously, this method requires running an HTTP server, and due to the Java security restrictions, it's also required that the server should be installed on the same machine which is running the TightVNC server. In this case, installation is simply copying the .class and .jar files into a directory that is under control of the HTTP server. Also, an HTML page should be created which will act as a the base document for the viewer applet (see an example named index.html in this distribution). 3. Running the viewer as a standalone application. Finally, the Java viewer can be executed locally on the client machine, but this method requires installation of either JRE (Java Runtime Environment) or JDK (Java Development Kit). If all the .class files are in the current directory, the Java viewer can be executed like this, from the command line: java VncViewer HOST vnchost PORT 5900 The parameters HOST and PORT are required, but there is a number of optional parameters as well (see the Parameters section below). Parameters ========== TightVNC Java viewer supports a number of parameters allowing you to customize its behaviour. Most parameter names copy settings available from the Options frame in the Java viewer. Both parameter names and their values are case-insensitive, with one exception for the "PASSWORD" parameter. Here is the full list of parameters supported in TightVNC Java viewer: --> "HOST" (no GUI equivalent) Value: host name or IP address of the VNC server. Default: in applet mode, the host from which the applet was loaded. This parameter tells the viewer which server to connect to. Normally, it's not needed, because default Java security policy allow connections from applets to the only one host anyway, and that is the host from which the applet was loaded. --> "PORT" (no GUI equivalent) Value: TCP port number on the VNC server. Default: none. This parameter is required in all cases. Note that this port is not the one used for HTTP connection from the browser, it is the port used for RFB connection. Usually, VNC servers use ports 58xx for HTTP connections, and ports 59xx for RFB connections. Thus, most likely, this parameter should be set to something like 5900, 5901 etc. --> "PASSWORD" Value: session password in plan text. Default: none, ask user. DO NOT EVER USE THIS PARAMETER, unless you really know what you are doing. It's extremely dangerous from the security point of view. When this parameter is set, the viewer won't ever ask for a password. --> "ENCPASSWORD" Value: encrypted session password in hex-ascii. Default: none, ask user. The same as the "PASSWORD" parameter but DES-encrypted using a fixed key. Its value should be represented in hex-ascii e.g. "494015f9a35e8b22". This parameter has higher priority over the "PASSWORD" parameter. DO NOT EVER USE THIS PARAMETER, unless you really know what you are doing. It's extremely dangerous from the security point of view, and encryption does not actually help here since the decryption key is always known. --> "Encoding" Values: "Raw", "RRE", "CoRRE", "Hextile", "Zlib", "Tight". Default: "Tight". The preferred encoding. "Hextile" is a good choice for fast networks, while "Tight" is better suited for low-bandwidth connections. From the other side, the "Tight" decoder in TightVNC Java viewer seems to be more efficient than "Hextile" decoder so it's possible that this default setting can be ok for fast networks too. --> "Compression level" Values: "Default", "1", "2", "3", "4", "5", "6", "7", "8", "9". Default: "Default". ;-) Use specified compression level for "Tight" and "Zlib" encodings. Level 1 uses minimum of CPU time on the server but achieves weak compression ratios. Level 9 offers best compression but may be slow in terms of CPU time consumption on the server side. Use high levels with very slow network connections, and low levels when working over higher-speed networks. The "Default" value means that the server's default compression level should be used. --> "JPEG image quality" Values: "JPEG off", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9". Default: "6". Use the specified image quality level in "Tight" encoding. Quality level 0 denotes bad image quality but very impressive compression ratios, while level 9 offers very good image quality at lower compression ratios. If the value is "JPEG off", the server will not use lossy JPEG compression in "Tight" encoding. --> "Cursor shape updates" Values: "Enable", "Ignore", "Disable". Default: "Enable". Cursor shape updates is a protocol extension used to handle remote cursor movements locally on the client side, saving bandwidth and eliminating delays in mouse pointer movement. Note that current implementation of cursor shape updates does not allow a client to track mouse cursor position at the server side. This means that clients would not see mouse cursor movements if mouse was moved either locally on the server, or by another remote VNC client. Set this parameter to "Disable" if you always want to see real cursor position on the remote side. Setting this option to "Ignore" is similar to "Enable" but the remote cursor will not be visible at all. This can be a reasonable setting if you don't care about cursor shape and don't want to see two mouse cursors, one above another. --> "Use CopyRect" Values: "Yes", "No". Default: "Yes". The "CopyRect" encoding saves bandwidth and drawing time when parts of the remote screen are moving around. Most likely, you don't want to change this setting. --> "Restricted colors" Values: "Yes", "No". Default: "No". If set to "No", then 24-bit color format is used to represent pixel data. If set to "Yes", then only 8 bits are used to represent each pixel. 8-bit color format can save bandwidth, but colors may look very inaccurate. --> "Mouse buttons 2 and 3" Values: "Normal", "Reversed". Default: "Normal". If set to "Reversed", then right mouse button (button 2) will act as it was middle mouse button (button 3), and vice versa. --> "View only" Values: "Yes", "No". Default: "No". If set to "Yes", then all keyboard and mouse events in the desktop window will be silently ignored and will not be passed to the remote side. --> "Share desktop" Values: "Yes", "No". Default: "Yes". Share the connection with other clients on the same VNC server. The exact behaviour in each case depends on the server configuration. --> "Open new window" (no GUI equivalent, applicable only in the applet mode) Values: "Yes", "No". Default: "No". Operate in a separate window. This makes possible resizing the desktop, and adds scroll bars when necessary. If the server supports variable desktop size, the window will resize automatically when remote desktop size changes. --> "Show controls" (no GUI equivalent) Values: "Yes", "No". Default: "Yes". Set to "No" if you want to get rid of that button panel at the top. --> "Offer relogin" (no GUI equivalent, not applicable in the applet mode) Values: "Yes", "No". Default: "Yes". If set to "No", the buttons "Login again" and "Close window" won't be shown on disconnects or after an error has occured. --> "Show offline desktop" (no GUI equivalent) Values: "Yes", "No". Default: "No". If set to "Yes", the viewer would continue to display desktop even if the remote side has closed the connection. In this case, if the button panel is enabled, then the "Disconnect" button would be changed to "Hide desktop" after the connection is lost. --> "Defer screen updates" (no GUI equivalent) Value: time in milliseconds. Default: "20". When updating the desktop contents after receiving an update from server, schedule repaint within the specified number of milliseconds. Small delay helps to coalesce several small updates into one drawing operation, improving CPU usage. Set this parameter to 0 to disable deferred updates. --> "Defer cursor updates" (no GUI equivalent) Value: time in milliseconds. Default: "10". When updating the desktop after moving the mouse, schedule repaint within the specified number of milliseconds. This setting makes sense only when "Cursor shape updates" parameter is set to "Enable". Small delay helps to coalesce several small updates into one drawing operation, improving CPU usage. Set this parameter to 0 to disable deferred cursor updates. --> "Defer update requests" (no GUI equivalent) Value: time in milliseconds. Default: "50". After processing an update received from server, wait for the specified number of milliseconds before requesting next screen update. Such delay will end immediately on every mouse or keyboard event if not in the "view only" mode. Small delay helps the server to coalesce several small updates into one framebuffer update, improving both bandwidth and CPU usage. Increasing the parameter value does not affect responsiveness on mouse and keyboard events, but causes delays in updating the screen when there is no mouse and keyboard activity on the client side. --> "SocketFactory" (no GUI equivalent) Value: name of the class. Default: none. This option provides the way to define an alternate I/O implementation. The dynamically referenced class must implement a SocketFactory interface, and create a Socket, as configured by this parameter. See the source in the SocketFactory.class. RECORDING VNC SESSIONS ====================== Current version of the TightVNC Java viewer is able to record VNC (RFB) sessions in files for later playback. The data format in saved session files is compatible with the rfbproxy program written by Tim Waugh. Most important thing about session recording is that it's supported only if Java security manager allows access to local filesystem. Typically, it would not work for unsigned applets. To use this feature, either use TightVNC Java viewer as a standalone application (Java Runtime Environment or Java Development Kit should be installed), or as a signed applet. The code checks if it's possible to support session recording, and if everything's fine, the new "Record" button should appear in the button panel. Pressing this button opens new window which controls session recording. The GUI is pretty self-explained. Other important facts about session recording: --> All sessions are recorded in the 24-bit color format. If you use restricted colors (8-bit format), it will be temporarly switched to 24-bit mode during session recording. --> All sessions are recorded with cursor shape updates turned off. This is necessary to represent remote cursor movements in recorded sessions. --> Closing and re-opening the recording control window does not affect the recording. It's not necessary to keep that window open during recording a session. --> Avoid using Zlib encoding when recording sessions. It's ok if you started recording BEFORE the connection to the VNC server has been established, but if you started recording during an active session, all Zlib sessions will be saved Raw-encoded (that is, without compression at all). Zlib decoding depends on the pixel data received earlier, thus saving the data received from the server at an arbitrary moment is not sufficient to decompress it correctly. And there is no way to say Zlib decoder to reset decompressor's state -- that's a limitation of the Zlib encoder. The viewer could re-compress raw pixel data again before saving Zlib-encoded sessions, but unfortunately Java API does not allow to flush zlib data streams making it impossible to save Zlib-encoded RFB pixel data without using native code. --> Usually, Tight encoding is the most suitable one for session recording, but some of the issues described above for the Zlib encoding affect the Tight encoding as well. Unlike Zlib sessions, Tight-encoded sessions are always saved Tight-encoded, but the viewer has to re-compress parts of data to synchronize encoder's and decoder's zlib streams. And, due to Java zlib API limitations, zlib streams' states have to be reset on each compressed rectangle, causing compression ratios to be lower than in the original VNC session. If you want to achieve the best possible performance, turn recording on BEFORE connecting to the VNC server, otherwise CPU usage and compression ratios may be notably less efficient. HINTS ===== --> To refresh remote desktop in the view-only mode, press "r" or "R" on the keyboard. ACKNOWLEDGEMENTS ================ This distribution contains Java DES software by Dave Zimmerman and Jef Poskanzer . This is: Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee is hereby granted, provided that this copyright notice is kept intact. WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. Copyright (C) 1996 by Jef Poskanzer . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Visit the ACME Labs Java page for up-to-date versions of this and other fine Java utilities: http://www.acme.com/java/ tightvnc-java-1.2.7.orig/HTTPConnectSocketFactory.java0100644000076500007650000000463407557537775021751 0ustar olaluolalu// // Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // HTTPConnectSocketFactory.java together with HTTPConnectSocket.java // implement an alternate way to connect to VNC servers via one or two // HTTP proxies supporting the HTTP CONNECT method. // import java.applet.*; import java.net.*; import java.io.*; class HTTPConnectSocketFactory implements SocketFactory { public Socket createSocket(String host, int port, Applet applet) throws IOException { return createSocket(host, port, applet.getParameter("PROXYHOST1"), applet.getParameter("PROXYPORT1")); } public Socket createSocket(String host, int port, String[] args) throws IOException { return createSocket(host, port, readArg(args, "PROXYHOST1"), readArg(args, "PROXYPORT1")); } public Socket createSocket(String host, int port, String proxyHost, String proxyPortStr) throws IOException { int proxyPort = 0; if (proxyPortStr != null) { try { proxyPort = Integer.parseInt(proxyPortStr); } catch (NumberFormatException e) { } } if (proxyHost == null || proxyPort == 0) { System.out.println("Incomplete parameter list for HTTPConnectSocket"); return new Socket(host, port); } System.out.println("HTTP CONNECT via proxy " + proxyHost + " port " + proxyPort); HTTPConnectSocket s = new HTTPConnectSocket(host, port, proxyHost, proxyPort); return (Socket)s; } private String readArg(String[] args, String name) { for (int i = 0; i < args.length; i += 2) { if (args[i].equalsIgnoreCase(name)) { try { return args[i+1]; } catch (Exception e) { return null; } } } return null; } } tightvnc-java-1.2.7.orig/index.html0100644000076500007650000000110007564143230016243 0ustar olaluolalu TightVNC desktop
TightVNC site tightvnc-java-1.2.7.orig/LICENCE.TXT0100644000076500007650000004312007165133673015730 0ustar olaluolalu GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. tightvnc-java-1.2.7.orig/AuthPanel.java0100644000076500007650000000565607452363226017023 0ustar olaluolalu// // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // import java.awt.*; import java.awt.event.*; // // The panel which implements the user authentication scheme // class AuthPanel extends Panel implements ActionListener { Label title, retry, prompt; TextField password; Button ok; // // Constructor. // public AuthPanel() { title = new Label("VNC Authentication",Label.CENTER); title.setFont(new Font("Helvetica", Font.BOLD, 18)); prompt = new Label("Password:",Label.CENTER); password = new TextField(10); password.setForeground(Color.black); password.setBackground(Color.white); password.setEchoChar('*'); ok = new Button("OK"); retry = new Label("",Label.CENTER); retry.setFont(new Font("Courier", Font.BOLD, 16)); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); setLayout(gridbag); gbc.gridwidth = GridBagConstraints.REMAINDER; gridbag.setConstraints(title,gbc); add(title); gbc.fill = GridBagConstraints.HORIZONTAL; gridbag.setConstraints(retry,gbc); add(retry); gbc.fill = GridBagConstraints.NONE; gbc.gridwidth = 1; gridbag.setConstraints(prompt,gbc); add(prompt); gridbag.setConstraints(password,gbc); add(password); password.addActionListener(this); gbc.ipady = 10; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(0,20,0,0); gbc.ipadx = 40; gridbag.setConstraints(ok,gbc); add(ok); ok.addActionListener(this); } // // Move keyboard focus to the password text field object. // public void moveFocusToPasswordField() { password.requestFocus(); } // // This method is called when a button is pressed or return is // pressed in the password text field. // public synchronized void actionPerformed(ActionEvent evt) { if (evt.getSource() == password || evt.getSource() == ok) { password.setEnabled(false); notify(); } } // // retry(). // public void retry() { retry.setText("Sorry. Try again."); password.setEnabled(true); password.setText(""); moveFocusToPasswordField(); } } tightvnc-java-1.2.7.orig/ClipboardFrame.java0100644000076500007650000000625407417630251020003 0ustar olaluolalu// // Copyright (C) 2001 HorizonLive.com, Inc. All Rights Reserved. // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // Clipboard frame. // import java.awt.*; import java.awt.event.*; class ClipboardFrame extends Frame implements WindowListener, ActionListener { TextArea textArea; Button clearButton, closeButton; String selection; VncViewer viewer; // // Constructor. // ClipboardFrame(VncViewer v) { super("TightVNC Clipboard"); viewer = v; GridBagLayout gridbag = new GridBagLayout(); setLayout(gridbag); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.BOTH; gbc.weighty = 1.0; textArea = new TextArea(5, 40); gridbag.setConstraints(textArea, gbc); add(textArea); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1.0; gbc.weighty = 0.0; gbc.gridwidth = 1; clearButton = new Button("Clear"); gridbag.setConstraints(clearButton, gbc); add(clearButton); clearButton.addActionListener(this); closeButton = new Button("Close"); gridbag.setConstraints(closeButton, gbc); add(closeButton); closeButton.addActionListener(this); pack(); addWindowListener(this); } // // Set the cut text from the RFB server. // void setCutText(String text) { selection = text; textArea.setText(text); if (isVisible()) { textArea.selectAll(); } } // // When the focus leaves the window, see if we have new cut text and // if so send it to the RFB server. // public void windowDeactivated (WindowEvent evt) { if (selection != null && !selection.equals(textArea.getText())) { selection = textArea.getText(); viewer.setCutText(selection); } } // // Close our window properly. // public void windowClosing(WindowEvent evt) { setVisible(false); } // // Ignore window events we're not interested in. // public void windowActivated(WindowEvent evt) {} public void windowOpened(WindowEvent evt) {} public void windowClosed(WindowEvent evt) {} public void windowIconified(WindowEvent evt) {} public void windowDeiconified(WindowEvent evt) {} // // Respond to button presses // public void actionPerformed(ActionEvent evt) { if (evt.getSource() == clearButton) { textArea.setText(""); } else if (evt.getSource() == closeButton) { setVisible(false); } } } tightvnc-java-1.2.7.orig/index.vnc0100644000076500007650000000151607564127260016105 0ustar olaluolalu $USER's $DESKTOP desktop ($DISPLAY) $PARAMS
TightVNC site tightvnc-java-1.2.7.orig/MANIFEST.MF0100644000076500007650000000005407564144030015706 0ustar olaluolaluManifest-Version: 1.0 Main-Class: VncViewer tightvnc-java-1.2.7.orig/RfbProto.java0100644000076500007650000006253107557537527016707 0ustar olaluolalu// // Copyright (C) 2001,2002 HorizonLive.com, Inc. All Rights Reserved. // Copyright (C) 2001,2002 Constantin Kaplinsky. All Rights Reserved. // Copyright (C) 2000 Tridia Corporation. All Rights Reserved. // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // RfbProto.java // import java.io.*; import java.awt.*; import java.awt.event.*; import java.net.Socket; import java.util.zip.*; class RfbProto { final String versionMsg = "RFB 003.003\n"; final static int ConnFailed = 0, NoAuth = 1, VncAuth = 2; final static int VncAuthOK = 0, VncAuthFailed = 1, VncAuthTooMany = 2; final static int FramebufferUpdate = 0, SetColourMapEntries = 1, Bell = 2, ServerCutText = 3; final int SetPixelFormat = 0, FixColourMapEntries = 1, SetEncodings = 2, FramebufferUpdateRequest = 3, KeyboardEvent = 4, PointerEvent = 5, ClientCutText = 6; final static int EncodingRaw = 0, EncodingCopyRect = 1, EncodingRRE = 2, EncodingCoRRE = 4, EncodingHextile = 5, EncodingZlib = 6, EncodingTight = 7, EncodingCompressLevel0 = 0xFFFFFF00, EncodingQualityLevel0 = 0xFFFFFFE0, EncodingXCursor = 0xFFFFFF10, EncodingRichCursor = 0xFFFFFF11, EncodingPointerPos = 0xFFFFFF18, EncodingLastRect = 0xFFFFFF20, EncodingNewFBSize = 0xFFFFFF21; final static int MaxNormalEncoding = 7; final int HextileRaw = (1 << 0); final int HextileBackgroundSpecified = (1 << 1); final int HextileForegroundSpecified = (1 << 2); final int HextileAnySubrects = (1 << 3); final int HextileSubrectsColoured = (1 << 4); final static int TightExplicitFilter = 0x04; final static int TightFill = 0x08; final static int TightJpeg = 0x09; final static int TightMaxSubencoding = 0x09; final static int TightFilterCopy = 0x00; final static int TightFilterPalette = 0x01; final static int TightFilterGradient = 0x02; final static int TightMinToCompress = 12; String host; int port; Socket sock; DataInputStream is; OutputStream os; SessionRecorder rec; boolean inNormalProtocol = false; VncViewer viewer; // Java on UNIX does not call keyPressed() on some keys, for example // swedish keys To prevent our workaround to produce duplicate // keypresses on JVMs that actually works, keep track of if // keyPressed() for a "broken" key was called or not. boolean brokenKeyPressed = false; // This will be set to true on the first framebuffer update // containing Zlib- or Tight-encoded data. boolean wereZlibUpdates = false; // This will be set to false if the startSession() was called after // we have received at least one Zlib- or Tight-encoded framebuffer // update. boolean recordFromBeginning = true; // This fields are needed to show warnings about inefficiently saved // sessions only once per each saved session file. boolean zlibWarningShown; boolean tightWarningShown; // Before starting to record each saved session, we set this field // to 0, and increment on each framebuffer update. We don't flush // the SessionRecorder data into the file before the second update. // This allows us to write initial framebuffer update with zero // timestamp, to let the player show initial desktop before // playback. int numUpdatesInSession; // If true, informs that the RFB socket was closed. private boolean closed; // // Constructor. Make TCP connection to RFB server. // RfbProto(String h, int p, VncViewer v) throws IOException { viewer = v; host = h; port = p; if (viewer.socketFactory == null) { sock = new Socket(host, port); } else { try { Class factoryClass = Class.forName(viewer.socketFactory); SocketFactory factory = (SocketFactory)factoryClass.newInstance(); if (viewer.inAnApplet) sock = factory.createSocket(host, port, viewer); else sock = factory.createSocket(host, port, viewer.mainArgs); } catch(Exception e) { e.printStackTrace(); throw new IOException(e.getMessage()); } } is = new DataInputStream(new BufferedInputStream(sock.getInputStream(), 16384)); os = sock.getOutputStream(); } synchronized void close() { try { sock.close(); closed = true; System.out.println("RFB socket closed"); if (rec != null) { rec.close(); rec = null; } } catch (Exception e) { e.printStackTrace(); } } synchronized boolean closed() { return closed; } // // Read server's protocol version message // int serverMajor, serverMinor; void readVersionMsg() throws Exception { byte[] b = new byte[12]; is.readFully(b); if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) { throw new Exception("Host " + host + " port " + port + " is not an RFB server"); } serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); } // // Write our protocol version message // void writeVersionMsg() throws IOException { os.write(versionMsg.getBytes()); } // // Find out the authentication scheme. // int readAuthScheme() throws Exception { int authScheme = is.readInt(); switch (authScheme) { case ConnFailed: int reasonLen = is.readInt(); byte[] reason = new byte[reasonLen]; is.readFully(reason); throw new Exception(new String(reason)); case NoAuth: case VncAuth: return authScheme; default: throw new Exception("Unknown authentication scheme from RFB server: " + authScheme); } } // // Write the client initialisation message // void writeClientInit() throws IOException { if (viewer.options.shareDesktop) { os.write(1); } else { os.write(0); } viewer.options.disableShareDesktop(); } // // Read the server initialisation message // String desktopName; int framebufferWidth, framebufferHeight; int bitsPerPixel, depth; boolean bigEndian, trueColour; int redMax, greenMax, blueMax, redShift, greenShift, blueShift; void readServerInit() throws IOException { framebufferWidth = is.readUnsignedShort(); framebufferHeight = is.readUnsignedShort(); bitsPerPixel = is.readUnsignedByte(); depth = is.readUnsignedByte(); bigEndian = (is.readUnsignedByte() != 0); trueColour = (is.readUnsignedByte() != 0); redMax = is.readUnsignedShort(); greenMax = is.readUnsignedShort(); blueMax = is.readUnsignedShort(); redShift = is.readUnsignedByte(); greenShift = is.readUnsignedByte(); blueShift = is.readUnsignedByte(); byte[] pad = new byte[3]; is.readFully(pad); int nameLength = is.readInt(); byte[] name = new byte[nameLength]; is.readFully(name); desktopName = new String(name); inNormalProtocol = true; } // // Create session file and write initial protocol messages into it. // void startSession(String fname) throws IOException { rec = new SessionRecorder(fname); rec.writeHeader(); rec.write(versionMsg.getBytes()); rec.writeIntBE(NoAuth); rec.writeShortBE(framebufferWidth); rec.writeShortBE(framebufferHeight); byte[] fbsServerInitMsg = { 32, 24, 0, 1, 0, (byte)0xFF, 0, (byte)0xFF, 0, (byte)0xFF, 16, 8, 0, 0, 0, 0 }; rec.write(fbsServerInitMsg); rec.writeIntBE(desktopName.length()); rec.write(desktopName.getBytes()); numUpdatesInSession = 0; if (wereZlibUpdates) recordFromBeginning = false; zlibWarningShown = false; tightWarningShown = false; } // // Close session file. // void closeSession() throws IOException { if (rec != null) { rec.close(); rec = null; } } // // Set new framebuffer size // void setFramebufferSize(int width, int height) { framebufferWidth = width; framebufferHeight = height; } // // Read the server message type // int readServerMessageType() throws IOException { int msgType = is.readUnsignedByte(); // If the session is being recorded: if (rec != null) { if (msgType == Bell) { // Save Bell messages in session files. rec.writeByte(msgType); if (numUpdatesInSession > 0) rec.flush(); } } return msgType; } // // Read a FramebufferUpdate message // int updateNRects; void readFramebufferUpdate() throws IOException { is.readByte(); updateNRects = is.readUnsignedShort(); // If the session is being recorded: if (rec != null) { rec.writeByte(FramebufferUpdate); rec.writeByte(0); rec.writeShortBE(updateNRects); } numUpdatesInSession++; } // Read a FramebufferUpdate rectangle header int updateRectX, updateRectY, updateRectW, updateRectH, updateRectEncoding; void readFramebufferUpdateRectHdr() throws Exception { updateRectX = is.readUnsignedShort(); updateRectY = is.readUnsignedShort(); updateRectW = is.readUnsignedShort(); updateRectH = is.readUnsignedShort(); updateRectEncoding = is.readInt(); if (updateRectEncoding == EncodingZlib || updateRectEncoding == EncodingTight) wereZlibUpdates = true; // If the session is being recorded: if (rec != null) { if (numUpdatesInSession > 1) rec.flush(); // Flush the output on each rectangle. rec.writeShortBE(updateRectX); rec.writeShortBE(updateRectY); rec.writeShortBE(updateRectW); rec.writeShortBE(updateRectH); if (updateRectEncoding == EncodingZlib && !recordFromBeginning) { // Here we cannot write Zlib-encoded rectangles because the // decoder won't be able to reproduce zlib stream state. if (!zlibWarningShown) { System.out.println("Warning: Raw encoding will be used " + "instead of Zlib in recorded session."); zlibWarningShown = true; } rec.writeIntBE(EncodingRaw); } else { rec.writeIntBE(updateRectEncoding); if (updateRectEncoding == EncodingTight && !recordFromBeginning && !tightWarningShown) { System.out.println("Warning: Re-compressing Tight-encoded " + "updates for session recording."); tightWarningShown = true; } } } if (updateRectEncoding < 0 || updateRectEncoding > MaxNormalEncoding) return; if (updateRectX + updateRectW > framebufferWidth || updateRectY + updateRectH > framebufferHeight) { throw new Exception("Framebuffer update rectangle too large: " + updateRectW + "x" + updateRectH + " at (" + updateRectX + "," + updateRectY + ")"); } } // Read CopyRect source X and Y. int copyRectSrcX, copyRectSrcY; void readCopyRect() throws IOException { copyRectSrcX = is.readUnsignedShort(); copyRectSrcY = is.readUnsignedShort(); // If the session is being recorded: if (rec != null) { rec.writeShortBE(copyRectSrcX); rec.writeShortBE(copyRectSrcY); } } // // Read a ServerCutText message // String readServerCutText() throws IOException { byte[] pad = new byte[3]; is.readFully(pad); int len = is.readInt(); byte[] text = new byte[len]; is.readFully(text); return new String(text); } // // Read an integer in compact representation (1..3 bytes). // Such format is used as a part of the Tight encoding. // Also, this method records data if session recording is active and // the viewer's recordFromBeginning variable is set to true. // int readCompactLen() throws IOException { int[] portion = new int[3]; portion[0] = is.readUnsignedByte(); int byteCount = 1; int len = portion[0] & 0x7F; if ((portion[0] & 0x80) != 0) { portion[1] = is.readUnsignedByte(); byteCount++; len |= (portion[1] & 0x7F) << 7; if ((portion[1] & 0x80) != 0) { portion[2] = is.readUnsignedByte(); byteCount++; len |= (portion[2] & 0xFF) << 14; } } if (rec != null && recordFromBeginning) for (int i = 0; i < byteCount; i++) rec.writeByte(portion[i]); return len; } // // Write a FramebufferUpdateRequest message // void writeFramebufferUpdateRequest(int x, int y, int w, int h, boolean incremental) throws IOException { byte[] b = new byte[10]; b[0] = (byte) FramebufferUpdateRequest; b[1] = (byte) (incremental ? 1 : 0); b[2] = (byte) ((x >> 8) & 0xff); b[3] = (byte) (x & 0xff); b[4] = (byte) ((y >> 8) & 0xff); b[5] = (byte) (y & 0xff); b[6] = (byte) ((w >> 8) & 0xff); b[7] = (byte) (w & 0xff); b[8] = (byte) ((h >> 8) & 0xff); b[9] = (byte) (h & 0xff); os.write(b); } // // Write a SetPixelFormat message // void writeSetPixelFormat(int bitsPerPixel, int depth, boolean bigEndian, boolean trueColour, int redMax, int greenMax, int blueMax, int redShift, int greenShift, int blueShift) throws IOException { byte[] b = new byte[20]; b[0] = (byte) SetPixelFormat; b[4] = (byte) bitsPerPixel; b[5] = (byte) depth; b[6] = (byte) (bigEndian ? 1 : 0); b[7] = (byte) (trueColour ? 1 : 0); b[8] = (byte) ((redMax >> 8) & 0xff); b[9] = (byte) (redMax & 0xff); b[10] = (byte) ((greenMax >> 8) & 0xff); b[11] = (byte) (greenMax & 0xff); b[12] = (byte) ((blueMax >> 8) & 0xff); b[13] = (byte) (blueMax & 0xff); b[14] = (byte) redShift; b[15] = (byte) greenShift; b[16] = (byte) blueShift; os.write(b); } // // Write a FixColourMapEntries message. The values in the red, green and // blue arrays are from 0 to 65535. // void writeFixColourMapEntries(int firstColour, int nColours, int[] red, int[] green, int[] blue) throws IOException { byte[] b = new byte[6 + nColours * 6]; b[0] = (byte) FixColourMapEntries; b[2] = (byte) ((firstColour >> 8) & 0xff); b[3] = (byte) (firstColour & 0xff); b[4] = (byte) ((nColours >> 8) & 0xff); b[5] = (byte) (nColours & 0xff); for (int i = 0; i < nColours; i++) { b[6 + i * 6] = (byte) ((red[i] >> 8) & 0xff); b[6 + i * 6 + 1] = (byte) (red[i] & 0xff); b[6 + i * 6 + 2] = (byte) ((green[i] >> 8) & 0xff); b[6 + i * 6 + 3] = (byte) (green[i] & 0xff); b[6 + i * 6 + 4] = (byte) ((blue[i] >> 8) & 0xff); b[6 + i * 6 + 5] = (byte) (blue[i] & 0xff); } os.write(b); } // // Write a SetEncodings message // void writeSetEncodings(int[] encs, int len) throws IOException { byte[] b = new byte[4 + 4 * len]; b[0] = (byte) SetEncodings; b[2] = (byte) ((len >> 8) & 0xff); b[3] = (byte) (len & 0xff); for (int i = 0; i < len; i++) { b[4 + 4 * i] = (byte) ((encs[i] >> 24) & 0xff); b[5 + 4 * i] = (byte) ((encs[i] >> 16) & 0xff); b[6 + 4 * i] = (byte) ((encs[i] >> 8) & 0xff); b[7 + 4 * i] = (byte) (encs[i] & 0xff); } os.write(b); } // // Write a ClientCutText message // void writeClientCutText(String text) throws IOException { byte[] b = new byte[8 + text.length()]; b[0] = (byte) ClientCutText; b[4] = (byte) ((text.length() >> 24) & 0xff); b[5] = (byte) ((text.length() >> 16) & 0xff); b[6] = (byte) ((text.length() >> 8) & 0xff); b[7] = (byte) (text.length() & 0xff); System.arraycopy(text.getBytes(), 0, b, 8, text.length()); os.write(b); } // // A buffer for putting pointer and keyboard events before being sent. This // is to ensure that multiple RFB events generated from a single Java Event // will all be sent in a single network packet. The maximum possible // length is 4 modifier down events, a single key event followed by 4 // modifier up events i.e. 9 key events or 72 bytes. // byte[] eventBuf = new byte[72]; int eventBufLen; // Useful shortcuts for modifier masks. final static int CTRL_MASK = InputEvent.CTRL_MASK; final static int SHIFT_MASK = InputEvent.SHIFT_MASK; final static int META_MASK = InputEvent.META_MASK; final static int ALT_MASK = InputEvent.ALT_MASK; // // Write a pointer event message. We may need to send modifier key events // around it to set the correct modifier state. // int pointerMask = 0; void writePointerEvent(MouseEvent evt) throws IOException { int modifiers = evt.getModifiers(); int mask2 = 2; int mask3 = 4; if (viewer.options.reverseMouseButtons2And3) { mask2 = 4; mask3 = 2; } // Note: For some reason, AWT does not set BUTTON1_MASK on left // button presses. Here we think that it was the left button if // modifiers do not include BUTTON2_MASK or BUTTON3_MASK. if (evt.getID() == MouseEvent.MOUSE_PRESSED) { if ((modifiers & InputEvent.BUTTON2_MASK) != 0) { pointerMask = mask2; modifiers &= ~ALT_MASK; } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { pointerMask = mask3; modifiers &= ~META_MASK; } else { pointerMask = 1; } } else if (evt.getID() == MouseEvent.MOUSE_RELEASED) { pointerMask = 0; if ((modifiers & InputEvent.BUTTON2_MASK) != 0) { modifiers &= ~ALT_MASK; } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { modifiers &= ~META_MASK; } } eventBufLen = 0; writeModifierKeyEvents(modifiers); int x = evt.getX(); int y = evt.getY(); if (x < 0) x = 0; if (y < 0) y = 0; eventBuf[eventBufLen++] = (byte) PointerEvent; eventBuf[eventBufLen++] = (byte) pointerMask; eventBuf[eventBufLen++] = (byte) ((x >> 8) & 0xff); eventBuf[eventBufLen++] = (byte) (x & 0xff); eventBuf[eventBufLen++] = (byte) ((y >> 8) & 0xff); eventBuf[eventBufLen++] = (byte) (y & 0xff); // // Always release all modifiers after an "up" event // if (pointerMask == 0) { writeModifierKeyEvents(0); } os.write(eventBuf, 0, eventBufLen); } // // Write a key event message. We may need to send modifier key events // around it to set the correct modifier state. Also we need to translate // from the Java key values to the X keysym values used by the RFB protocol. // void writeKeyEvent(KeyEvent evt) throws IOException { int keyChar = evt.getKeyChar(); // // Ignore event if only modifiers were pressed. // // Some JVMs return 0 instead of CHAR_UNDEFINED in getKeyChar(). if (keyChar == 0) keyChar = KeyEvent.CHAR_UNDEFINED; if (keyChar == KeyEvent.CHAR_UNDEFINED) { int code = evt.getKeyCode(); if (code == KeyEvent.VK_CONTROL || code == KeyEvent.VK_SHIFT || code == KeyEvent.VK_META || code == KeyEvent.VK_ALT) return; } // // Key press or key release? // boolean down = (evt.getID() == KeyEvent.KEY_PRESSED); int key; if (evt.isActionKey()) { // // An action key should be one of the following. // If not then just ignore the event. // switch(evt.getKeyCode()) { case KeyEvent.VK_HOME: key = 0xff50; break; case KeyEvent.VK_LEFT: key = 0xff51; break; case KeyEvent.VK_UP: key = 0xff52; break; case KeyEvent.VK_RIGHT: key = 0xff53; break; case KeyEvent.VK_DOWN: key = 0xff54; break; case KeyEvent.VK_PAGE_UP: key = 0xff55; break; case KeyEvent.VK_PAGE_DOWN: key = 0xff56; break; case KeyEvent.VK_END: key = 0xff57; break; case KeyEvent.VK_INSERT: key = 0xff63; break; case KeyEvent.VK_F1: key = 0xffbe; break; case KeyEvent.VK_F2: key = 0xffbf; break; case KeyEvent.VK_F3: key = 0xffc0; break; case KeyEvent.VK_F4: key = 0xffc1; break; case KeyEvent.VK_F5: key = 0xffc2; break; case KeyEvent.VK_F6: key = 0xffc3; break; case KeyEvent.VK_F7: key = 0xffc4; break; case KeyEvent.VK_F8: key = 0xffc5; break; case KeyEvent.VK_F9: key = 0xffc6; break; case KeyEvent.VK_F10: key = 0xffc7; break; case KeyEvent.VK_F11: key = 0xffc8; break; case KeyEvent.VK_F12: key = 0xffc9; break; default: return; } } else { // // A "normal" key press. Ordinary ASCII characters go straight through. // For CTRL-, CTRL is sent separately so just send . // Backspace, tab, return, escape and delete have special keysyms. // Anything else we ignore. // key = keyChar; if (key < 0x20) { if (evt.isControlDown()) { key += 0x60; } else { switch(key) { case KeyEvent.VK_BACK_SPACE: key = 0xff08; break; case KeyEvent.VK_TAB: key = 0xff09; break; case KeyEvent.VK_ENTER: key = 0xff0d; break; case KeyEvent.VK_ESCAPE: key = 0xff1b; break; } } } else if (key == 0x7f) { // Delete key = 0xffff; } else if (key > 0xff) { // JDK1.1 on X incorrectly passes some keysyms straight through, // so we do too. JDK1.1.4 seems to have fixed this. // The keysyms passed are 0xff00 .. XK_BackSpace .. XK_Delete if ((key < 0xff00) || (key > 0xffff)) return; } } // Fake keyPresses for keys that only generates keyRelease events if ((key == 0xe5) || (key == 0xc5) || // XK_aring / XK_Aring (key == 0xe4) || (key == 0xc4) || // XK_adiaeresis / XK_Adiaeresis (key == 0xf6) || (key == 0xd6) || // XK_odiaeresis / XK_Odiaeresis (key == 0xa7) || (key == 0xbd) || // XK_section / XK_onehalf (key == 0xa3)) { // XK_sterling // Make sure we do not send keypress events twice on platforms // with correct JVMs (those that actually report KeyPress for all // keys) if (down) brokenKeyPressed = true; if (!down && !brokenKeyPressed) { // We've got a release event for this key, but haven't received // a press. Fake it. eventBufLen = 0; writeModifierKeyEvents(evt.getModifiers()); writeKeyEvent(key, true); os.write(eventBuf, 0, eventBufLen); } if (!down) brokenKeyPressed = false; } eventBufLen = 0; writeModifierKeyEvents(evt.getModifiers()); writeKeyEvent(key, down); // Always release all modifiers after an "up" event if (!down) writeModifierKeyEvents(0); os.write(eventBuf, 0, eventBufLen); } // // Add a raw key event with the given X keysym to eventBuf. // void writeKeyEvent(int keysym, boolean down) { eventBuf[eventBufLen++] = (byte) KeyboardEvent; eventBuf[eventBufLen++] = (byte) (down ? 1 : 0); eventBuf[eventBufLen++] = (byte) 0; eventBuf[eventBufLen++] = (byte) 0; eventBuf[eventBufLen++] = (byte) ((keysym >> 24) & 0xff); eventBuf[eventBufLen++] = (byte) ((keysym >> 16) & 0xff); eventBuf[eventBufLen++] = (byte) ((keysym >> 8) & 0xff); eventBuf[eventBufLen++] = (byte) (keysym & 0xff); } // // Write key events to set the correct modifier state. // int oldModifiers = 0; void writeModifierKeyEvents(int newModifiers) { if ((newModifiers & CTRL_MASK) != (oldModifiers & CTRL_MASK)) writeKeyEvent(0xffe3, (newModifiers & CTRL_MASK) != 0); if ((newModifiers & SHIFT_MASK) != (oldModifiers & SHIFT_MASK)) writeKeyEvent(0xffe1, (newModifiers & SHIFT_MASK) != 0); if ((newModifiers & META_MASK) != (oldModifiers & META_MASK)) writeKeyEvent(0xffe7, (newModifiers & META_MASK) != 0); if ((newModifiers & ALT_MASK) != (oldModifiers & ALT_MASK)) writeKeyEvent(0xffe9, (newModifiers & ALT_MASK) != 0); oldModifiers = newModifiers; } // // Compress and write the data into the recorded session file. This // method assumes the recording is on (rec != null). // void recordCompressedData(byte[] data, int off, int len) throws IOException { Deflater deflater = new Deflater(); deflater.setInput(data, off, len); int bufSize = len + len / 100 + 12; byte[] buf = new byte[bufSize]; deflater.finish(); int compressedSize = deflater.deflate(buf); recordCompactLen(compressedSize); rec.write(buf, 0, compressedSize); } void recordCompressedData(byte[] data) throws IOException { recordCompressedData(data, 0, data.length); } // // Write an integer in compact representation (1..3 bytes) into the // recorded session file. This method assumes the recording is on // (rec != null). // void recordCompactLen(int len) throws IOException { byte[] buf = new byte[3]; int bytes = 0; buf[bytes++] = (byte)(len & 0x7F); if (len > 0x7F) { buf[bytes-1] |= 0x80; buf[bytes++] = (byte)(len >> 7 & 0x7F); if (len > 0x3FFF) { buf[bytes-1] |= 0x80; buf[bytes++] = (byte)(len >> 14 & 0xFF); } } rec.write(buf, 0, bytes); } } tightvnc-java-1.2.7.orig/VncViewer.java0100644000076500007650000005021007562463316017037 0ustar olaluolalu// // Copyright (C) 2001,2002 HorizonLive.com, Inc. All Rights Reserved. // Copyright (C) 2002 Constantin Kaplinsky. All Rights Reserved. // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // VncViewer.java - the VNC viewer applet. This class mainly just sets up the // user interface, leaving it to the VncCanvas to do the actual rendering of // a VNC desktop. // import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class VncViewer extends java.applet.Applet implements java.lang.Runnable, WindowListener { boolean inAnApplet = true; boolean inSeparateFrame = false; // // main() is called when run as a java program from the command line. // It simply runs the applet inside a newly-created frame. // public static void main(String[] argv) { VncViewer v = new VncViewer(); v.mainArgs = argv; v.inAnApplet = false; v.inSeparateFrame = true; v.init(); v.start(); } String[] mainArgs; RfbProto rfb; Thread rfbThread; Frame vncFrame; Container vncContainer; ScrollPane desktopScrollPane; GridBagLayout gridbag; ButtonPanel buttonPanel; AuthPanel authenticator; VncCanvas vc; OptionsFrame options; ClipboardFrame clipboard; RecordingFrame rec; // Control session recording. Object recordingSync; String sessionFileName; boolean recordingActive; boolean recordingStatusChanged; String cursorUpdatesDef; String eightBitColorsDef; // Variables read from parameter values. String socketFactory; String host; int port; String passwordParam; String encPasswordParam; boolean showControls; boolean offerRelogin; boolean showOfflineDesktop; int deferScreenUpdates; int deferCursorUpdates; int deferUpdateRequests; // // init() // public void init() { readParameters(); if (inSeparateFrame) { vncFrame = new Frame("TightVNC"); if (!inAnApplet) { vncFrame.add("Center", this); } vncContainer = vncFrame; } else { vncContainer = this; } recordingSync = new Object(); options = new OptionsFrame(this); clipboard = new ClipboardFrame(this); authenticator = new AuthPanel(); if (RecordingFrame.checkSecurity()) rec = new RecordingFrame(this); sessionFileName = null; recordingActive = false; recordingStatusChanged = false; cursorUpdatesDef = null; eightBitColorsDef = null; if (inSeparateFrame) vncFrame.addWindowListener(this); rfbThread = new Thread(this); rfbThread.start(); } public void update(Graphics g) { } // // run() - executed by the rfbThread to deal with the RFB socket. // public void run() { gridbag = new GridBagLayout(); vncContainer.setLayout(gridbag); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.anchor = GridBagConstraints.NORTHWEST; if (showControls) { buttonPanel = new ButtonPanel(this); gridbag.setConstraints(buttonPanel, gbc); vncContainer.add(buttonPanel); } try { connectAndAuthenticate(); doProtocolInitialisation(); vc = new VncCanvas(this); gbc.weightx = 1.0; gbc.weighty = 1.0; if (inSeparateFrame) { // Create a panel which itself is resizeable and can hold // non-resizeable VncCanvas component at the top left corner. Panel canvasPanel = new Panel(); canvasPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); canvasPanel.add(vc); // Create a ScrollPane which will hold a panel with VncCanvas // inside. desktopScrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED); gbc.fill = GridBagConstraints.BOTH; gridbag.setConstraints(desktopScrollPane, gbc); desktopScrollPane.add(canvasPanel); // Finally, add our ScrollPane to the Frame window. vncFrame.add(desktopScrollPane); vncFrame.setTitle(rfb.desktopName); vncFrame.pack(); vc.resizeDesktopFrame(); } else { // Just add the VncCanvas component to the Applet. gridbag.setConstraints(vc, gbc); add(vc); validate(); } if (showControls) buttonPanel.enableButtons(); vc.processNormalProtocol(); } catch (NoRouteToHostException e) { fatalError("Network error: no route to server: " + host, e); } catch (UnknownHostException e) { fatalError("Network error: server name unknown: " + host, e); } catch (ConnectException e) { fatalError("Network error: could not connect to server: " + host + ":" + port, e); } catch (EOFException e) { if (showOfflineDesktop) { e.printStackTrace(); System.out.println("Network error: remote side closed connection"); if (vc != null) { vc.enableInput(false); } if (inSeparateFrame) { vncFrame.setTitle(rfb.desktopName + " [disconnected]"); } if (rfb != null && !rfb.closed()) rfb.close(); if (showControls && buttonPanel != null) { buttonPanel.disableButtonsOnDisconnect(); if (inSeparateFrame) { vncFrame.pack(); } else { validate(); } } } else { fatalError("Network error: remote side closed connection", e); } } catch (IOException e) { String str = e.getMessage(); if (str != null && str.length() != 0) { fatalError("Network Error: " + str, e); } else { fatalError(e.toString(), e); } } catch (Exception e) { String str = e.getMessage(); if (str != null && str.length() != 0) { fatalError("Error: " + str, e); } else { fatalError(e.toString(), e); } } } // // Connect to the RFB server and authenticate the user. // void connectAndAuthenticate() throws Exception { // If "ENCPASSWORD" parameter is set, decrypt the password into // the passwordParam string. if (encPasswordParam != null) { // ENCPASSWORD is hexascii-encoded. Decode. byte[] pw = {0, 0, 0, 0, 0, 0, 0, 0}; int len = encPasswordParam.length() / 2; if (len > 8) len = 8; for (int i = 0; i < len; i++) { String hex = encPasswordParam.substring(i*2, i*2+2); Integer x = new Integer(Integer.parseInt(hex, 16)); pw[i] = x.byteValue(); } // Decrypt the password. byte[] key = {23, 82, 107, 6, 35, 78, 88, 7}; DesCipher des = new DesCipher(key); des.decrypt(pw, 0, pw, 0); passwordParam = new String(pw); } // If a password parameter ("PASSWORD" or "ENCPASSWORD") is set, // don't ask user a password, get one from passwordParam instead. // Authentication failures would be fatal. if (passwordParam != null) { if (inSeparateFrame) { vncFrame.pack(); vncFrame.show(); } else { validate(); } if (!tryAuthenticate(passwordParam)) { throw new Exception("VNC authentication failed"); } return; } // There is no "PASSWORD" or "ENCPASSWORD" parameters -- ask user // for a password, try to authenticate, retry on authentication // failures. GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.ipadx = 100; gbc.ipady = 50; gridbag.setConstraints(authenticator, gbc); vncContainer.add(authenticator); if (inSeparateFrame) { vncFrame.pack(); vncFrame.show(); } else { validate(); // FIXME: here moveFocusToPasswordField() does not always work // under Netscape 4.7x/Java 1.1.5/Linux. It seems like this call // is being executed before the password field of the // authenticator is fully drawn and activated, therefore // requestFocus() does not work. Currently, I don't know how to // solve this problem. // -- const authenticator.moveFocusToPasswordField(); } while (true) { // Wait for user entering a password. synchronized(authenticator) { try { authenticator.wait(); } catch (InterruptedException e) { } } // Try to authenticate with a given password. if (tryAuthenticate(authenticator.password.getText())) break; // Retry on authentication failure. authenticator.retry(); } vncContainer.remove(authenticator); } // // Try to authenticate with a given password. // boolean tryAuthenticate(String pw) throws Exception { rfb = new RfbProto(host, port, this); rfb.readVersionMsg(); System.out.println("RFB server supports protocol version " + rfb.serverMajor + "." + rfb.serverMinor); rfb.writeVersionMsg(); int authScheme = rfb.readAuthScheme(); switch (authScheme) { case RfbProto.NoAuth: System.out.println("No authentication needed"); return true; case RfbProto.VncAuth: byte[] challenge = new byte[16]; rfb.is.readFully(challenge); if (pw.length() > 8) pw = pw.substring(0, 8); // Truncate to 8 chars // vncEncryptBytes in the UNIX libvncauth truncates password // after the first zero byte. We do to. int firstZero = pw.indexOf(0); if (firstZero != -1) pw = pw.substring(0, firstZero); byte[] key = {0, 0, 0, 0, 0, 0, 0, 0}; System.arraycopy(pw.getBytes(), 0, key, 0, pw.length()); DesCipher des = new DesCipher(key); des.encrypt(challenge, 0, challenge, 0); des.encrypt(challenge, 8, challenge, 8); rfb.os.write(challenge); int authResult = rfb.is.readInt(); switch (authResult) { case RfbProto.VncAuthOK: System.out.println("VNC authentication succeeded"); return true; case RfbProto.VncAuthFailed: System.out.println("VNC authentication failed"); break; case RfbProto.VncAuthTooMany: throw new Exception("VNC authentication failed - too many tries"); default: throw new Exception("Unknown VNC authentication result " + authResult); } break; default: throw new Exception("Unknown VNC authentication scheme " + authScheme); } return false; } // // Do the rest of the protocol initialisation. // void doProtocolInitialisation() throws IOException { rfb.writeClientInit(); rfb.readServerInit(); System.out.println("Desktop name is " + rfb.desktopName); System.out.println("Desktop size is " + rfb.framebufferWidth + " x " + rfb.framebufferHeight); setEncodings(); } // // Send current encoding list to the RFB server. // void setEncodings() { try { if (rfb != null && rfb.inNormalProtocol) { rfb.writeSetEncodings(options.encodings, options.nEncodings); if (vc != null) { vc.softCursorFree(); } } } catch (Exception e) { e.printStackTrace(); } } // // setCutText() - send the given cut text to the RFB server. // void setCutText(String text) { try { if (rfb != null && rfb.inNormalProtocol) { rfb.writeClientCutText(text); } } catch (Exception e) { e.printStackTrace(); } } // // Order change in session recording status. To stop recording, pass // null in place of the fname argument. // void setRecordingStatus(String fname) { synchronized(recordingSync) { sessionFileName = fname; recordingStatusChanged = true; } } // // Start or stop session recording. Returns true if this method call // causes recording of a new session. // boolean checkRecordingStatus() throws IOException { synchronized(recordingSync) { if (recordingStatusChanged) { recordingStatusChanged = false; if (sessionFileName != null) { startRecording(); return true; } else { stopRecording(); } } } return false; } // // Start session recording. // protected void startRecording() throws IOException { synchronized(recordingSync) { if (!recordingActive) { // Save settings to restore them after recording the session. cursorUpdatesDef = options.choices[options.cursorUpdatesIndex].getSelectedItem(); eightBitColorsDef = options.choices[options.eightBitColorsIndex].getSelectedItem(); // Set options to values suitable for recording. options.choices[options.cursorUpdatesIndex].select("Disable"); options.choices[options.cursorUpdatesIndex].setEnabled(false); options.setEncodings(); options.choices[options.eightBitColorsIndex].select("No"); options.choices[options.eightBitColorsIndex].setEnabled(false); options.setColorFormat(); } else { rfb.closeSession(); } System.out.println("Recording the session in " + sessionFileName); rfb.startSession(sessionFileName); recordingActive = true; } } // // Stop session recording. // protected void stopRecording() throws IOException { synchronized(recordingSync) { if (recordingActive) { // Restore options. options.choices[options.cursorUpdatesIndex].select(cursorUpdatesDef); options.choices[options.cursorUpdatesIndex].setEnabled(true); options.setEncodings(); options.choices[options.eightBitColorsIndex].select(eightBitColorsDef); options.choices[options.eightBitColorsIndex].setEnabled(true); options.setColorFormat(); rfb.closeSession(); System.out.println("Session recording stopped."); } sessionFileName = null; recordingActive = false; } } // // readParameters() - read parameters from the html source or from the // command line. On the command line, the arguments are just a sequence of // param_name/param_value pairs where the names and values correspond to // those expected in the html applet tag source. // public void readParameters() { host = readParameter("HOST", !inAnApplet); if (host == null) { host = getCodeBase().getHost(); if (host.equals("")) { fatalError("HOST parameter not specified"); } } String str = readParameter("PORT", true); port = Integer.parseInt(str); if (inAnApplet) { str = readParameter("Open New Window", false); if (str != null && str.equalsIgnoreCase("Yes")) inSeparateFrame = true; } encPasswordParam = readParameter("ENCPASSWORD", false); if (encPasswordParam == null) passwordParam = readParameter("PASSWORD", false); // "Show Controls" set to "No" disables button panel. showControls = true; str = readParameter("Show Controls", false); if (str != null && str.equalsIgnoreCase("No")) showControls = false; // "Offer Relogin" set to "No" disables "Login again" and "Close // window" buttons under error messages in applet mode. offerRelogin = true; str = readParameter("Offer Relogin", false); if (str != null && str.equalsIgnoreCase("No")) offerRelogin = false; // Do we continue showing desktop on remote disconnect? showOfflineDesktop = false; str = readParameter("Show Offline Desktop", false); if (str != null && str.equalsIgnoreCase("Yes")) showOfflineDesktop = true; // Fine tuning options. deferScreenUpdates = readIntParameter("Defer screen updates", 20); deferCursorUpdates = readIntParameter("Defer cursor updates", 10); deferUpdateRequests = readIntParameter("Defer update requests", 50); // SocketFactory. socketFactory = readParameter("SocketFactory", false); } public String readParameter(String name, boolean required) { if (inAnApplet) { String s = getParameter(name); if ((s == null) && required) { fatalError(name + " parameter not specified"); } return s; } for (int i = 0; i < mainArgs.length; i += 2) { if (mainArgs[i].equalsIgnoreCase(name)) { try { return mainArgs[i+1]; } catch (Exception e) { if (required) { fatalError(name + " parameter not specified"); } return null; } } } if (required) { fatalError(name + " parameter not specified"); } return null; } int readIntParameter(String name, int defaultValue) { String str = readParameter(name, false); int result = defaultValue; if (str != null) { try { result = Integer.parseInt(str); } catch (NumberFormatException e) { } } return result; } // // moveFocusToDesktop() - move keyboard focus either to the // VncCanvas or to the AuthPanel. // void moveFocusToDesktop() { if (vncContainer != null) { if (vc != null && vncContainer.isAncestorOf(vc)) { vc.requestFocus(); } else if (vncContainer.isAncestorOf(authenticator)) { authenticator.moveFocusToPasswordField(); } } } // // disconnect() - close connection to server. // synchronized public void disconnect() { System.out.println("Disconnect"); if (rfb != null && !rfb.closed()) rfb.close(); options.dispose(); clipboard.dispose(); if (rec != null) rec.dispose(); if (inAnApplet) { showMessage("Disconnected"); } else { System.exit(0); } } // // fatalError() - print out a fatal error message. // synchronized public void fatalError(String str) { System.out.println(str); if (inAnApplet) { // vncContainer null, applet not inited, // can not present the error to the user. Thread.currentThread().stop(); } else { System.exit(1); } } synchronized public void fatalError(String str, Exception e) { if (rfb != null) { // Not necessary to show error message if the error was caused // by I/O problems after the rfb.close() method call. if (rfb.closed()) { System.out.println("RFB thread finished"); return; } rfb.close(); } e.printStackTrace(); System.out.println(str); if (inAnApplet) { showMessage(str); } else { System.exit(1); } } // // Show message text and optionally "Relogin" and "Close" buttons. // void showMessage(String msg) { vncContainer.removeAll(); Label errLabel = new Label(msg, Label.CENTER); errLabel.setFont(new Font("Helvetica", Font.PLAIN, 12)); if (offerRelogin) { Panel gridPanel = new Panel(new GridLayout(0, 1)); Panel outerPanel = new Panel(new FlowLayout(FlowLayout.LEFT)); outerPanel.add(gridPanel); vncContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 16)); vncContainer.add(outerPanel); Panel textPanel = new Panel(new FlowLayout(FlowLayout.CENTER)); textPanel.add(errLabel); gridPanel.add(textPanel); gridPanel.add(new ReloginPanel(this)); } else { vncContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 30)); vncContainer.add(errLabel); } if (inSeparateFrame) { vncFrame.pack(); } else { validate(); } } // // This method is called before the applet is destroyed. // public void destroy() { System.out.println("Destroying applet"); vncContainer.removeAll(); options.dispose(); clipboard.dispose(); if (rec != null) rec.dispose(); if (rfb != null && !rfb.closed()) rfb.close(); if (inSeparateFrame) vncFrame.dispose(); } // // Close application properly on window close event. // public void windowClosing(WindowEvent evt) { System.out.println("Closing window"); if (rfb != null) disconnect(); vncFrame.dispose(); if (!inAnApplet) { System.exit(0); } } // // Move the keyboard focus to the password field on window activation. // public void windowActivated(WindowEvent evt) { if (vncFrame.isAncestorOf(authenticator)) authenticator.moveFocusToPasswordField(); } // // Ignore window events we're not interested in. // public void windowDeactivated (WindowEvent evt) {} public void windowOpened(WindowEvent evt) {} public void windowClosed(WindowEvent evt) {} public void windowIconified(WindowEvent evt) {} public void windowDeiconified(WindowEvent evt) {} } tightvnc-java-1.2.7.orig/VncCanvas.java0100644000076500007650000011310607562463316017015 0ustar olaluolalu// // Copyright (C) 2001,2002 HorizonLive.com, Inc. All Rights Reserved. // Copyright (C) 2001,2002 Constantin Kaplinsky. All Rights Reserved. // Copyright (C) 2000 Tridia Corporation. All Rights Reserved. // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import java.lang.*; import java.util.zip.*; // // VncCanvas is a subclass of Canvas which draws a VNC desktop on it. // class VncCanvas extends Canvas implements KeyListener, MouseListener, MouseMotionListener { VncViewer viewer; RfbProto rfb; ColorModel cm8, cm24; Color[] colors; int bytesPixel; Image memImage; Graphics memGraphics; Image rawPixelsImage; MemoryImageSource pixelsSource; byte[] pixels8; int[] pixels24; // Zlib encoder's data. byte[] zlibBuf; int zlibBufLen = 0; Inflater zlibInflater; // Tight encoder's data. final static int tightZlibBufferSize = 512; Inflater[] tightInflaters; // Since JPEG images are loaded asynchronously, we have to remember // their position in the framebuffer. Also, this jpegRect object is // used for synchronization between the rfbThread and a JVM's thread // which decodes and loads JPEG images. Rectangle jpegRect; // True if we process keyboard and mouse events. boolean inputEnabled; // // The constructor. // VncCanvas(VncViewer v) throws IOException { viewer = v; rfb = viewer.rfb; tightInflaters = new Inflater[4]; cm8 = new DirectColorModel(8, 7, (7 << 3), (3 << 6)); cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF); colors = new Color[256]; for (int i = 0; i < 256; i++) colors[i] = new Color(cm8.getRGB(i)); setPixelFormat(); inputEnabled = false; if (!viewer.options.viewOnly) enableInput(true); // Keyboard listener is enabled even in view-only mode, to catch // 'r' or 'R' key presses used to request screen update. addKeyListener(this); } // // Callback methods to determine geometry of our Component. // public Dimension getPreferredSize() { return new Dimension(rfb.framebufferWidth, rfb.framebufferHeight); } public Dimension getMinimumSize() { return new Dimension(rfb.framebufferWidth, rfb.framebufferHeight); } public Dimension getMaximumSize() { return new Dimension(rfb.framebufferWidth, rfb.framebufferHeight); } // // All painting is performed here. // public void update(Graphics g) { paint(g); } public void paint(Graphics g) { synchronized(memImage) { g.drawImage(memImage, 0, 0, null); } if (showSoftCursor) { int x0 = cursorX - hotX, y0 = cursorY - hotY; Rectangle r = new Rectangle(x0, y0, cursorWidth, cursorHeight); if (r.intersects(g.getClipBounds())) { g.drawImage(softCursor, x0, y0, null); } } } // // Override the ImageObserver interface method to handle drawing of // JPEG-encoded data. // public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { if ((infoflags & (ALLBITS | ABORT)) == 0) { return true; // We need more image data. } else { // If the whole image is available, draw it now. if ((infoflags & ALLBITS) != 0) { if (jpegRect != null) { synchronized(jpegRect) { memGraphics.drawImage(img, jpegRect.x, jpegRect.y, null); scheduleRepaint(jpegRect.x, jpegRect.y, jpegRect.width, jpegRect.height); jpegRect.notify(); } } } return false; // All image data was processed. } } // // Start/stop receiving mouse events. Keyboard events are received // even in view-only mode, because we want to map the 'r' key to the // screen refreshing function. // public synchronized void enableInput(boolean enable) { if (enable && !inputEnabled) { inputEnabled = true; addMouseListener(this); addMouseMotionListener(this); if (viewer.showControls) { viewer.buttonPanel.enableRemoteAccessControls(true); } } else if (!enable && inputEnabled) { inputEnabled = false; removeMouseListener(this); removeMouseMotionListener(this); if (viewer.showControls) { viewer.buttonPanel.enableRemoteAccessControls(false); } } } public void setPixelFormat() throws IOException { if (viewer.options.eightBitColors) { rfb.writeSetPixelFormat(8, 8, false, true, 7, 7, 3, 0, 3, 6); bytesPixel = 1; } else { rfb.writeSetPixelFormat(32, 24, false, true, 255, 255, 255, 16, 8, 0); bytesPixel = 4; } updateFramebufferSize(); } void updateFramebufferSize() { // Useful shortcuts. int fbWidth = rfb.framebufferWidth; int fbHeight = rfb.framebufferHeight; // Create new off-screen image either if it does not exist, or if // its geometry should be changed. It's not necessary to replace // existing image if only pixel format should be changed. if (memImage == null) { memImage = viewer.createImage(fbWidth, fbHeight); memGraphics = memImage.getGraphics(); } else if (memImage.getWidth(null) != fbWidth || memImage.getHeight(null) != fbHeight) { synchronized(memImage) { memImage = viewer.createImage(fbWidth, fbHeight); memGraphics = memImage.getGraphics(); } } // Images with raw pixels should be re-allocated on every change // of geometry or pixel format. if (bytesPixel == 1) { pixels24 = null; pixels8 = new byte[fbWidth * fbHeight]; pixelsSource = new MemoryImageSource(fbWidth, fbHeight, cm8, pixels8, 0, fbWidth); } else { pixels8 = null; pixels24 = new int[fbWidth * fbHeight]; pixelsSource = new MemoryImageSource(fbWidth, fbHeight, cm24, pixels24, 0, fbWidth); } pixelsSource.setAnimated(true); rawPixelsImage = createImage(pixelsSource); // Update the size of desktop containers. if (viewer.inSeparateFrame) { if (viewer.desktopScrollPane != null) resizeDesktopFrame(); } else { setSize(fbWidth, fbHeight); } viewer.moveFocusToDesktop(); } void resizeDesktopFrame() { setSize(rfb.framebufferWidth, rfb.framebufferHeight); // FIXME: Find a better way to determine correct size of a // ScrollPane. -- const Insets insets = viewer.desktopScrollPane.getInsets(); viewer.desktopScrollPane.setSize(rfb.framebufferWidth + 2 * Math.min(insets.left, insets.right), rfb.framebufferHeight + 2 * Math.min(insets.top, insets.bottom)); viewer.vncFrame.pack(); // Try to limit the frame size to the screen size. Dimension screenSize = viewer.vncFrame.getToolkit().getScreenSize(); Dimension frameSize = viewer.vncFrame.getSize(); Dimension newSize = frameSize; // Reduce Screen Size by 30 pixels in each direction; // This is a (poor) attempt to account for // 1) Menu bar on Macintosh (should really also account for // Dock on OSX). Usually 22px on top of screen. // 2) Taxkbar on Windows (usually about 28 px on bottom) // 3) Other obstructions. screenSize.height -= 30; screenSize.width -= 30; boolean needToResizeFrame = false; if (frameSize.height > screenSize.height) { newSize.height = screenSize.height; needToResizeFrame = true; } if (frameSize.width > screenSize.width) { newSize.width = screenSize.width; needToResizeFrame = true; } if (needToResizeFrame) { viewer.vncFrame.setSize(newSize); } viewer.desktopScrollPane.doLayout(); } // // processNormalProtocol() - executed by the rfbThread to deal with the // RFB socket. // public void processNormalProtocol() throws Exception { // Start/stop session recording if necessary. viewer.checkRecordingStatus(); rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, rfb.framebufferHeight, false); // // main dispatch loop // while (true) { // Read message type from the server. int msgType = rfb.readServerMessageType(); // Process the message depending on its type. switch (msgType) { case RfbProto.FramebufferUpdate: rfb.readFramebufferUpdate(); boolean cursorPosReceived = false; for (int i = 0; i < rfb.updateNRects; i++) { rfb.readFramebufferUpdateRectHdr(); int rx = rfb.updateRectX, ry = rfb.updateRectY; int rw = rfb.updateRectW, rh = rfb.updateRectH; if (rfb.updateRectEncoding == rfb.EncodingLastRect) break; if (rfb.updateRectEncoding == rfb.EncodingNewFBSize) { rfb.setFramebufferSize(rw, rh); updateFramebufferSize(); break; } if (rfb.updateRectEncoding == rfb.EncodingXCursor || rfb.updateRectEncoding == rfb.EncodingRichCursor) { handleCursorShapeUpdate(rfb.updateRectEncoding, rx, ry, rw, rh); continue; } if (rfb.updateRectEncoding == rfb.EncodingPointerPos) { softCursorMove(rx, ry); cursorPosReceived = true; continue; } switch (rfb.updateRectEncoding) { case RfbProto.EncodingRaw: handleRawRect(rx, ry, rw, rh); break; case RfbProto.EncodingCopyRect: handleCopyRect(rx, ry, rw, rh); break; case RfbProto.EncodingRRE: handleRRERect(rx, ry, rw, rh); break; case RfbProto.EncodingCoRRE: handleCoRRERect(rx, ry, rw, rh); break; case RfbProto.EncodingHextile: handleHextileRect(rx, ry, rw, rh); break; case RfbProto.EncodingZlib: handleZlibRect(rx, ry, rw, rh); break; case RfbProto.EncodingTight: handleTightRect(rx, ry, rw, rh); break; default: throw new Exception("Unknown RFB rectangle encoding " + rfb.updateRectEncoding); } } boolean fullUpdateNeeded = false; // Start/stop session recording if necessary. Request full // update if a new session file was opened. if (viewer.checkRecordingStatus()) fullUpdateNeeded = true; // Defer framebuffer update request if necessary. But wake up // immediately on keyboard or mouse event. Also, don't sleep // if there is some data to receive, or if the last update // included a PointerPos message. if (viewer.deferUpdateRequests > 0 && rfb.is.available() == 0 && !cursorPosReceived) { synchronized(rfb) { try { rfb.wait(viewer.deferUpdateRequests); } catch (InterruptedException e) { } } } // Before requesting framebuffer update, check if the pixel // format should be changed. If it should, request full update // instead of an incremental one. if (viewer.options.eightBitColors != (bytesPixel == 1)) { setPixelFormat(); fullUpdateNeeded = true; } rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, rfb.framebufferHeight, !fullUpdateNeeded); break; case RfbProto.SetColourMapEntries: throw new Exception("Can't handle SetColourMapEntries message"); case RfbProto.Bell: Toolkit.getDefaultToolkit().beep(); break; case RfbProto.ServerCutText: String s = rfb.readServerCutText(); viewer.clipboard.setCutText(s); break; default: throw new Exception("Unknown RFB message type " + msgType); } } } // // Handle a raw rectangle. The second form with paint==false is used // by the Hextile decoder for raw-encoded tiles. // void handleRawRect(int x, int y, int w, int h) throws IOException { handleRawRect(x, y, w, h, true); } void handleRawRect(int x, int y, int w, int h, boolean paint) throws IOException { if (bytesPixel == 1) { for (int dy = y; dy < y + h; dy++) { rfb.is.readFully(pixels8, dy * rfb.framebufferWidth + x, w); if (rfb.rec != null) { rfb.rec.write(pixels8, dy * rfb.framebufferWidth + x, w); } } } else { byte[] buf = new byte[w * 4]; int i, offset; for (int dy = y; dy < y + h; dy++) { rfb.is.readFully(buf); if (rfb.rec != null) { rfb.rec.write(buf); } offset = dy * rfb.framebufferWidth + x; for (i = 0; i < w; i++) { pixels24[offset + i] = (buf[i * 4 + 2] & 0xFF) << 16 | (buf[i * 4 + 1] & 0xFF) << 8 | (buf[i * 4] & 0xFF); } } } handleUpdatedPixels(x, y, w, h); if (paint) scheduleRepaint(x, y, w, h); } // // Handle a CopyRect rectangle. // void handleCopyRect(int x, int y, int w, int h) throws IOException { rfb.readCopyRect(); memGraphics.copyArea(rfb.copyRectSrcX, rfb.copyRectSrcY, w, h, x - rfb.copyRectSrcX, y - rfb.copyRectSrcY); scheduleRepaint(x, y, w, h); } // // Handle an RRE-encoded rectangle. // void handleRRERect(int x, int y, int w, int h) throws IOException { int nSubrects = rfb.is.readInt(); byte[] bg_buf = new byte[bytesPixel]; rfb.is.readFully(bg_buf); Color pixel; if (bytesPixel == 1) { pixel = colors[bg_buf[0] & 0xFF]; } else { pixel = new Color(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF); } memGraphics.setColor(pixel); memGraphics.fillRect(x, y, w, h); byte[] buf = new byte[nSubrects * (bytesPixel + 8)]; rfb.is.readFully(buf); DataInputStream ds = new DataInputStream(new ByteArrayInputStream(buf)); if (rfb.rec != null) { rfb.rec.writeIntBE(nSubrects); rfb.rec.write(bg_buf); rfb.rec.write(buf); } int sx, sy, sw, sh; for (int j = 0; j < nSubrects; j++) { if (bytesPixel == 1) { pixel = colors[ds.readUnsignedByte()]; } else { ds.skip(4); pixel = new Color(buf[j*12+2] & 0xFF, buf[j*12+1] & 0xFF, buf[j*12] & 0xFF); } sx = x + ds.readUnsignedShort(); sy = y + ds.readUnsignedShort(); sw = ds.readUnsignedShort(); sh = ds.readUnsignedShort(); memGraphics.setColor(pixel); memGraphics.fillRect(sx, sy, sw, sh); } scheduleRepaint(x, y, w, h); } // // Handle a CoRRE-encoded rectangle. // void handleCoRRERect(int x, int y, int w, int h) throws IOException { int nSubrects = rfb.is.readInt(); byte[] bg_buf = new byte[bytesPixel]; rfb.is.readFully(bg_buf); Color pixel; if (bytesPixel == 1) { pixel = colors[bg_buf[0] & 0xFF]; } else { pixel = new Color(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF); } memGraphics.setColor(pixel); memGraphics.fillRect(x, y, w, h); byte[] buf = new byte[nSubrects * (bytesPixel + 4)]; rfb.is.readFully(buf); if (rfb.rec != null) { rfb.rec.writeIntBE(nSubrects); rfb.rec.write(bg_buf); rfb.rec.write(buf); } int sx, sy, sw, sh; int i = 0; for (int j = 0; j < nSubrects; j++) { if (bytesPixel == 1) { pixel = colors[buf[i++] & 0xFF]; } else { pixel = new Color(buf[i+2] & 0xFF, buf[i+1] & 0xFF, buf[i] & 0xFF); i += 4; } sx = x + (buf[i++] & 0xFF); sy = y + (buf[i++] & 0xFF); sw = buf[i++] & 0xFF; sh = buf[i++] & 0xFF; memGraphics.setColor(pixel); memGraphics.fillRect(sx, sy, sw, sh); } scheduleRepaint(x, y, w, h); } // // Handle a Hextile-encoded rectangle. // // These colors should be kept between handleHextileSubrect() calls. private Color hextile_bg, hextile_fg; void handleHextileRect(int x, int y, int w, int h) throws IOException { hextile_bg = new Color(0); hextile_fg = new Color(0); for (int ty = y; ty < y + h; ty += 16) { int th = 16; if (y + h - ty < 16) th = y + h - ty; for (int tx = x; tx < x + w; tx += 16) { int tw = 16; if (x + w - tx < 16) tw = x + w - tx; handleHextileSubrect(tx, ty, tw, th); } // Finished with a row of tiles, now let's show it. scheduleRepaint(x, y, w, h); } } // // Handle one tile in the Hextile-encoded data. // void handleHextileSubrect(int tx, int ty, int tw, int th) throws IOException { int subencoding = rfb.is.readUnsignedByte(); if (rfb.rec != null) { rfb.rec.writeByte(subencoding); } // Is it a raw-encoded sub-rectangle? if ((subencoding & rfb.HextileRaw) != 0) { handleRawRect(tx, ty, tw, th, false); return; } // Read and draw the background if specified. byte[] cbuf = new byte[bytesPixel]; if ((subencoding & rfb.HextileBackgroundSpecified) != 0) { rfb.is.readFully(cbuf); if (bytesPixel == 1) { hextile_bg = colors[cbuf[0] & 0xFF]; } else { hextile_bg = new Color(cbuf[2] & 0xFF, cbuf[1] & 0xFF, cbuf[0] & 0xFF); } if (rfb.rec != null) { rfb.rec.write(cbuf); } } memGraphics.setColor(hextile_bg); memGraphics.fillRect(tx, ty, tw, th); // Read the foreground color if specified. if ((subencoding & rfb.HextileForegroundSpecified) != 0) { rfb.is.readFully(cbuf); if (bytesPixel == 1) { hextile_fg = colors[cbuf[0] & 0xFF]; } else { hextile_fg = new Color(cbuf[2] & 0xFF, cbuf[1] & 0xFF, cbuf[0] & 0xFF); } if (rfb.rec != null) { rfb.rec.write(cbuf); } } // Done with this tile if there is no sub-rectangles. if ((subencoding & rfb.HextileAnySubrects) == 0) return; int nSubrects = rfb.is.readUnsignedByte(); int bufsize = nSubrects * 2; if ((subencoding & rfb.HextileSubrectsColoured) != 0) { bufsize += nSubrects * bytesPixel; } byte[] buf = new byte[bufsize]; rfb.is.readFully(buf); if (rfb.rec != null) { rfb.rec.writeByte(nSubrects); rfb.rec.write(buf); } int b1, b2, sx, sy, sw, sh; int i = 0; if ((subencoding & rfb.HextileSubrectsColoured) == 0) { // Sub-rectangles are all of the same color. memGraphics.setColor(hextile_fg); for (int j = 0; j < nSubrects; j++) { b1 = buf[i++] & 0xFF; b2 = buf[i++] & 0xFF; sx = tx + (b1 >> 4); sy = ty + (b1 & 0xf); sw = (b2 >> 4) + 1; sh = (b2 & 0xf) + 1; memGraphics.fillRect(sx, sy, sw, sh); } } else if (bytesPixel == 1) { // BGR233 (8-bit color) version for colored sub-rectangles. for (int j = 0; j < nSubrects; j++) { hextile_fg = colors[buf[i++] & 0xFF]; b1 = buf[i++] & 0xFF; b2 = buf[i++] & 0xFF; sx = tx + (b1 >> 4); sy = ty + (b1 & 0xf); sw = (b2 >> 4) + 1; sh = (b2 & 0xf) + 1; memGraphics.setColor(hextile_fg); memGraphics.fillRect(sx, sy, sw, sh); } } else { // Full-color (24-bit) version for colored sub-rectangles. for (int j = 0; j < nSubrects; j++) { hextile_fg = new Color(buf[i+2] & 0xFF, buf[i+1] & 0xFF, buf[i] & 0xFF); i += 4; b1 = buf[i++] & 0xFF; b2 = buf[i++] & 0xFF; sx = tx + (b1 >> 4); sy = ty + (b1 & 0xf); sw = (b2 >> 4) + 1; sh = (b2 & 0xf) + 1; memGraphics.setColor(hextile_fg); memGraphics.fillRect(sx, sy, sw, sh); } } } // // Handle a Zlib-encoded rectangle. // void handleZlibRect(int x, int y, int w, int h) throws Exception { int nBytes = rfb.is.readInt(); if (zlibBuf == null || zlibBufLen < nBytes) { zlibBufLen = nBytes * 2; zlibBuf = new byte[zlibBufLen]; } rfb.is.readFully(zlibBuf, 0, nBytes); if (rfb.rec != null && rfb.recordFromBeginning) { rfb.rec.writeIntBE(nBytes); rfb.rec.write(zlibBuf, 0, nBytes); } if (zlibInflater == null) { zlibInflater = new Inflater(); } zlibInflater.setInput(zlibBuf, 0, nBytes); if (bytesPixel == 1) { for (int dy = y; dy < y + h; dy++) { zlibInflater.inflate(pixels8, dy * rfb.framebufferWidth + x, w); if (rfb.rec != null && !rfb.recordFromBeginning) rfb.rec.write(pixels8, dy * rfb.framebufferWidth + x, w); } } else { byte[] buf = new byte[w * 4]; int i, offset; for (int dy = y; dy < y + h; dy++) { zlibInflater.inflate(buf); offset = dy * rfb.framebufferWidth + x; for (i = 0; i < w; i++) { pixels24[offset + i] = (buf[i * 4 + 2] & 0xFF) << 16 | (buf[i * 4 + 1] & 0xFF) << 8 | (buf[i * 4] & 0xFF); } if (rfb.rec != null && !rfb.recordFromBeginning) rfb.rec.write(buf); } } handleUpdatedPixels(x, y, w, h); scheduleRepaint(x, y, w, h); } // // Handle a Tight-encoded rectangle. // void handleTightRect(int x, int y, int w, int h) throws Exception { int comp_ctl = rfb.is.readUnsignedByte(); if (rfb.rec != null) { if (rfb.recordFromBeginning || comp_ctl == (rfb.TightFill << 4) || comp_ctl == (rfb.TightJpeg << 4)) { // Send data exactly as received. rfb.rec.writeByte(comp_ctl); } else { // Tell the decoder to flush each of the four zlib streams. rfb.rec.writeByte(comp_ctl | 0x0F); } } // Flush zlib streams if we are told by the server to do so. for (int stream_id = 0; stream_id < 4; stream_id++) { if ((comp_ctl & 1) != 0 && tightInflaters[stream_id] != null) { tightInflaters[stream_id] = null; } comp_ctl >>= 1; } // Check correctness of subencoding value. if (comp_ctl > rfb.TightMaxSubencoding) { throw new Exception("Incorrect tight subencoding: " + comp_ctl); } // Handle solid-color rectangles. if (comp_ctl == rfb.TightFill) { if (bytesPixel == 1) { int idx = rfb.is.readUnsignedByte(); memGraphics.setColor(colors[idx]); if (rfb.rec != null) { rfb.rec.writeByte(idx); } } else { byte[] buf = new byte[3]; rfb.is.readFully(buf); if (rfb.rec != null) { rfb.rec.write(buf); } Color bg = new Color(0xFF000000 | (buf[0] & 0xFF) << 16 | (buf[1] & 0xFF) << 8 | (buf[2] & 0xFF)); memGraphics.setColor(bg); } memGraphics.fillRect(x, y, w, h); scheduleRepaint(x, y, w, h); return; } if (comp_ctl == rfb.TightJpeg) { // Read JPEG data. byte[] jpegData = new byte[rfb.readCompactLen()]; rfb.is.readFully(jpegData); if (rfb.rec != null) { if (!rfb.recordFromBeginning) { rfb.recordCompactLen(jpegData.length); } rfb.rec.write(jpegData); } // Create an Image object from the JPEG data. Image jpegImage = Toolkit.getDefaultToolkit().createImage(jpegData); // Remember the rectangle where the image should be drawn. jpegRect = new Rectangle(x, y, w, h); // Let the imageUpdate() method do the actual drawing, here just // wait until the image is fully loaded and drawn. synchronized(jpegRect) { Toolkit.getDefaultToolkit().prepareImage(jpegImage, -1, -1, this); try { // Wait no longer than three seconds. jpegRect.wait(3000); } catch (InterruptedException e) { throw new Exception("Interrupted while decoding JPEG image"); } } // Done, jpegRect is not needed any more. jpegRect = null; return; } // Read filter id and parameters. int numColors = 0, rowSize = w; byte[] palette8 = new byte[2]; int[] palette24 = new int[256]; boolean useGradient = false; if ((comp_ctl & rfb.TightExplicitFilter) != 0) { int filter_id = rfb.is.readUnsignedByte(); if (rfb.rec != null) { rfb.rec.writeByte(filter_id); } if (filter_id == rfb.TightFilterPalette) { numColors = rfb.is.readUnsignedByte() + 1; if (rfb.rec != null) { rfb.rec.writeByte(numColors - 1); } if (bytesPixel == 1) { if (numColors != 2) { throw new Exception("Incorrect tight palette size: " + numColors); } rfb.is.readFully(palette8); if (rfb.rec != null) { rfb.rec.write(palette8); } } else { byte[] buf = new byte[numColors * 3]; rfb.is.readFully(buf); if (rfb.rec != null) { rfb.rec.write(buf); } for (int i = 0; i < numColors; i++) { palette24[i] = ((buf[i * 3] & 0xFF) << 16 | (buf[i * 3 + 1] & 0xFF) << 8 | (buf[i * 3 + 2] & 0xFF)); } } if (numColors == 2) rowSize = (w + 7) / 8; } else if (filter_id == rfb.TightFilterGradient) { useGradient = true; } else if (filter_id != rfb.TightFilterCopy) { throw new Exception("Incorrect tight filter id: " + filter_id); } } if (numColors == 0 && bytesPixel == 4) rowSize *= 3; // Read, optionally uncompress and decode data. int dataSize = h * rowSize; if (dataSize < rfb.TightMinToCompress) { // Data size is small - not compressed with zlib. if (numColors != 0) { // Indexed colors. byte[] indexedData = new byte[dataSize]; rfb.is.readFully(indexedData); if (rfb.rec != null) { rfb.rec.write(indexedData); } if (numColors == 2) { // Two colors. if (bytesPixel == 1) { decodeMonoData(x, y, w, h, indexedData, palette8); } else { decodeMonoData(x, y, w, h, indexedData, palette24); } } else { // 3..255 colors (assuming bytesPixel == 4). int i = 0; for (int dy = y; dy < y + h; dy++) { for (int dx = x; dx < x + w; dx++) { pixels24[dy * rfb.framebufferWidth + dx] = palette24[indexedData[i++] & 0xFF]; } } } } else if (useGradient) { // "Gradient"-processed data byte[] buf = new byte[w * h * 3]; rfb.is.readFully(buf); if (rfb.rec != null) { rfb.rec.write(buf); } decodeGradientData(x, y, w, h, buf); } else { // Raw truecolor data. if (bytesPixel == 1) { for (int dy = y; dy < y + h; dy++) { rfb.is.readFully(pixels8, dy * rfb.framebufferWidth + x, w); if (rfb.rec != null) { rfb.rec.write(pixels8, dy * rfb.framebufferWidth + x, w); } } } else { byte[] buf = new byte[w * 3]; int i, offset; for (int dy = y; dy < y + h; dy++) { rfb.is.readFully(buf); if (rfb.rec != null) { rfb.rec.write(buf); } offset = dy * rfb.framebufferWidth + x; for (i = 0; i < w; i++) { pixels24[offset + i] = (buf[i * 3] & 0xFF) << 16 | (buf[i * 3 + 1] & 0xFF) << 8 | (buf[i * 3 + 2] & 0xFF); } } } } } else { // Data was compressed with zlib. int zlibDataLen = rfb.readCompactLen(); byte[] zlibData = new byte[zlibDataLen]; rfb.is.readFully(zlibData); if (rfb.rec != null && rfb.recordFromBeginning) { rfb.rec.write(zlibData); } int stream_id = comp_ctl & 0x03; if (tightInflaters[stream_id] == null) { tightInflaters[stream_id] = new Inflater(); } Inflater myInflater = tightInflaters[stream_id]; myInflater.setInput(zlibData); byte[] buf = new byte[dataSize]; myInflater.inflate(buf); if (rfb.rec != null && !rfb.recordFromBeginning) { rfb.recordCompressedData(buf); } if (numColors != 0) { // Indexed colors. if (numColors == 2) { // Two colors. if (bytesPixel == 1) { decodeMonoData(x, y, w, h, buf, palette8); } else { decodeMonoData(x, y, w, h, buf, palette24); } } else { // More than two colors (assuming bytesPixel == 4). int i = 0; for (int dy = y; dy < y + h; dy++) { for (int dx = x; dx < x + w; dx++) { pixels24[dy * rfb.framebufferWidth + dx] = palette24[buf[i++] & 0xFF]; } } } } else if (useGradient) { // Compressed "Gradient"-filtered data (assuming bytesPixel == 4). decodeGradientData(x, y, w, h, buf); } else { // Compressed truecolor data. if (bytesPixel == 1) { int destOffset = y * rfb.framebufferWidth + x; for (int dy = 0; dy < h; dy++) { System.arraycopy(buf, dy * w, pixels8, destOffset, w); destOffset += rfb.framebufferWidth; } } else { int srcOffset = 0; int destOffset, i; for (int dy = 0; dy < h; dy++) { myInflater.inflate(buf); destOffset = (y + dy) * rfb.framebufferWidth + x; for (i = 0; i < w; i++) { pixels24[destOffset + i] = (buf[srcOffset] & 0xFF) << 16 | (buf[srcOffset + 1] & 0xFF) << 8 | (buf[srcOffset + 2] & 0xFF); srcOffset += 3; } } } } } handleUpdatedPixels(x, y, w, h); scheduleRepaint(x, y, w, h); } // // Decode 1bpp-encoded bi-color rectangle (8-bit and 24-bit versions). // void decodeMonoData(int x, int y, int w, int h, byte[] src, byte[] palette) { int dx, dy, n; int i = y * rfb.framebufferWidth + x; int rowBytes = (w + 7) / 8; byte b; for (dy = 0; dy < h; dy++) { for (dx = 0; dx < w / 8; dx++) { b = src[dy*rowBytes+dx]; for (n = 7; n >= 0; n--) pixels8[i++] = palette[b >> n & 1]; } for (n = 7; n >= 8 - w % 8; n--) { pixels8[i++] = palette[src[dy*rowBytes+dx] >> n & 1]; } i += (rfb.framebufferWidth - w); } } void decodeMonoData(int x, int y, int w, int h, byte[] src, int[] palette) { int dx, dy, n; int i = y * rfb.framebufferWidth + x; int rowBytes = (w + 7) / 8; byte b; for (dy = 0; dy < h; dy++) { for (dx = 0; dx < w / 8; dx++) { b = src[dy*rowBytes+dx]; for (n = 7; n >= 0; n--) pixels24[i++] = palette[b >> n & 1]; } for (n = 7; n >= 8 - w % 8; n--) { pixels24[i++] = palette[src[dy*rowBytes+dx] >> n & 1]; } i += (rfb.framebufferWidth - w); } } // // Decode data processed with the "Gradient" filter. // void decodeGradientData (int x, int y, int w, int h, byte[] buf) { int dx, dy, c; byte[] prevRow = new byte[w * 3]; byte[] thisRow = new byte[w * 3]; byte[] pix = new byte[3]; int[] est = new int[3]; int offset = y * rfb.framebufferWidth + x; for (dy = 0; dy < h; dy++) { /* First pixel in a row */ for (c = 0; c < 3; c++) { pix[c] = (byte)(prevRow[c] + buf[dy * w * 3 + c]); thisRow[c] = pix[c]; } pixels24[offset++] = (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF); /* Remaining pixels of a row */ for (dx = 1; dx < w; dx++) { for (c = 0; c < 3; c++) { est[c] = ((prevRow[dx * 3 + c] & 0xFF) + (pix[c] & 0xFF) - (prevRow[(dx-1) * 3 + c] & 0xFF)); if (est[c] > 0xFF) { est[c] = 0xFF; } else if (est[c] < 0x00) { est[c] = 0x00; } pix[c] = (byte)(est[c] + buf[(dy * w + dx) * 3 + c]); thisRow[dx * 3 + c] = pix[c]; } pixels24[offset++] = (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF); } System.arraycopy(thisRow, 0, prevRow, 0, w * 3); offset += (rfb.framebufferWidth - w); } } // // Display newly updated area of pixels. // void handleUpdatedPixels(int x, int y, int w, int h) { // Draw updated pixels of the off-screen image. pixelsSource.newPixels(x, y, w, h); memGraphics.setClip(x, y, w, h); memGraphics.drawImage(rawPixelsImage, 0, 0, null); memGraphics.setClip(0, 0, rfb.framebufferWidth, rfb.framebufferHeight); } // // Tell JVM to repaint specified desktop area. // void scheduleRepaint(int x, int y, int w, int h) { // Request repaint, deferred if necessary. repaint(viewer.deferScreenUpdates, x, y, w, h); } // // Handle events. // public void keyPressed(KeyEvent evt) { processLocalKeyEvent(evt); } public void keyReleased(KeyEvent evt) { processLocalKeyEvent(evt); } public void keyTyped(KeyEvent evt) { evt.consume(); } public void mousePressed(MouseEvent evt) { processLocalMouseEvent(evt, false); } public void mouseReleased(MouseEvent evt) { processLocalMouseEvent(evt, false); } public void mouseMoved(MouseEvent evt) { processLocalMouseEvent(evt, true); } public void mouseDragged(MouseEvent evt) { processLocalMouseEvent(evt, true); } public void processLocalKeyEvent(KeyEvent evt) { if (viewer.rfb != null && rfb.inNormalProtocol) { if (!inputEnabled) { if ((evt.getKeyChar() == 'r' || evt.getKeyChar() == 'R') && evt.getID() == KeyEvent.KEY_PRESSED ) { // Request screen update. try { rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, rfb.framebufferHeight, false); } catch (IOException e) { e.printStackTrace(); } } } else { // Input enabled. synchronized(rfb) { try { rfb.writeKeyEvent(evt); } catch (Exception e) { e.printStackTrace(); } rfb.notify(); } } } // Don't ever pass keyboard events to AWT for default processing. // Otherwise, pressing Tab would switch focus to ButtonPanel etc. evt.consume(); } public void processLocalMouseEvent(MouseEvent evt, boolean moved) { if (viewer.rfb != null && rfb.inNormalProtocol) { if (moved) { softCursorMove(evt.getX(), evt.getY()); } synchronized(rfb) { try { rfb.writePointerEvent(evt); } catch (Exception e) { e.printStackTrace(); } rfb.notify(); } } } // // Ignored events. // public void mouseClicked(MouseEvent evt) {} public void mouseEntered(MouseEvent evt) {} public void mouseExited(MouseEvent evt) {} ////////////////////////////////////////////////////////////////// // // Handle cursor shape updates (XCursor and RichCursor encodings). // boolean showSoftCursor = false; int[] softCursorPixels; MemoryImageSource softCursorSource; Image softCursor; int cursorX = 0, cursorY = 0; int cursorWidth, cursorHeight; int hotX, hotY; // // Handle cursor shape update (XCursor and RichCursor encodings). // synchronized void handleCursorShapeUpdate(int encodingType, int xhot, int yhot, int width, int height) throws IOException { int bytesPerRow = (width + 7) / 8; int bytesMaskData = bytesPerRow * height; softCursorFree(); if (width * height == 0) return; // Ignore cursor shape data if requested by user. if (viewer.options.ignoreCursorUpdates) { if (encodingType == rfb.EncodingXCursor) { rfb.is.skipBytes(6 + bytesMaskData * 2); } else { // rfb.EncodingRichCursor rfb.is.skipBytes(width * height + bytesMaskData); } return; } // Decode cursor pixel data. softCursorPixels = new int[width * height]; if (encodingType == rfb.EncodingXCursor) { // Read foreground and background colors of the cursor. byte[] rgb = new byte[6]; rfb.is.readFully(rgb); int[] colors = { (0xFF000000 | (rgb[3] & 0xFF) << 16 | (rgb[4] & 0xFF) << 8 | (rgb[5] & 0xFF)), (0xFF000000 | (rgb[0] & 0xFF) << 16 | (rgb[1] & 0xFF) << 8 | (rgb[2] & 0xFF)) }; // Read pixel and mask data. byte[] pixBuf = new byte[bytesMaskData]; rfb.is.readFully(pixBuf); byte[] maskBuf = new byte[bytesMaskData]; rfb.is.readFully(maskBuf); // Decode pixel data into softCursorPixels[]. byte pixByte, maskByte; int x, y, n, result; int i = 0; for (y = 0; y < height; y++) { for (x = 0; x < width / 8; x++) { pixByte = pixBuf[y * bytesPerRow + x]; maskByte = maskBuf[y * bytesPerRow + x]; for (n = 7; n >= 0; n--) { if ((maskByte >> n & 1) != 0) { result = colors[pixByte >> n & 1]; } else { result = 0; // Transparent pixel } softCursorPixels[i++] = result; } } for (n = 7; n >= 8 - width % 8; n--) { if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) { result = colors[pixBuf[y * bytesPerRow + x] >> n & 1]; } else { result = 0; // Transparent pixel } softCursorPixels[i++] = result; } } } else { // encodingType == rfb.EncodingRichCursor // Read pixel and mask data. byte[] pixBuf = new byte[width * height * bytesPixel]; rfb.is.readFully(pixBuf); byte[] maskBuf = new byte[bytesMaskData]; rfb.is.readFully(maskBuf); // Decode pixel data into softCursorPixels[]. byte pixByte, maskByte; int x, y, n, result; int i = 0; for (y = 0; y < height; y++) { for (x = 0; x < width / 8; x++) { maskByte = maskBuf[y * bytesPerRow + x]; for (n = 7; n >= 0; n--) { if ((maskByte >> n & 1) != 0) { if (bytesPixel == 1) { result = cm8.getRGB(pixBuf[i]); } else { result = 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF) << 16 | (pixBuf[i * 4 + 2] & 0xFF) << 8 | (pixBuf[i * 4 + 3] & 0xFF); } } else { result = 0; // Transparent pixel } softCursorPixels[i++] = result; } } for (n = 7; n >= 8 - width % 8; n--) { if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) { if (bytesPixel == 1) { result = cm8.getRGB(pixBuf[i]); } else { result = 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF) << 16 | (pixBuf[i * 4 + 2] & 0xFF) << 8 | (pixBuf[i * 4 + 3] & 0xFF); } } else { result = 0; // Transparent pixel } softCursorPixels[i++] = result; } } } // Draw the cursor on an off-screen image. softCursorSource = new MemoryImageSource(width, height, softCursorPixels, 0, width); softCursor = createImage(softCursorSource); // Set remaining data associated with cursor. cursorWidth = width; cursorHeight = height; hotX = xhot; hotY = yhot; showSoftCursor = true; // Show the cursor. repaint(viewer.deferCursorUpdates, cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight); } // // softCursorMove(). Moves soft cursor into a particular location. // synchronized void softCursorMove(int x, int y) { if (showSoftCursor) { repaint(viewer.deferCursorUpdates, cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight); repaint(viewer.deferCursorUpdates, x - hotX, y - hotY, cursorWidth, cursorHeight); } cursorX = x; cursorY = y; } // // softCursorFree(). Remove soft cursor, dispose resources. // synchronized void softCursorFree() { if (showSoftCursor) { showSoftCursor = false; softCursor = null; softCursorSource = null; softCursorPixels = null; repaint(viewer.deferCursorUpdates, cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight); } } } tightvnc-java-1.2.7.orig/ChangeLog0100644000076500007650000005073107571452427016047 0ustar olaluolalu2002-11-13 09:50 const_k * README: Version string changed, version 1.2.7. 2002-11-12 01:21 const_k * MANIFEST.MF, Makefile: Added a MANIFEST file with a Main-Class statement to allow easy execution of the JAR file, using java -jar command-line option. 2002-11-12 01:18 const_k * dir.mk: Removed dir.mk file. 2002-11-12 01:15 const_k * index.html: Applet height increased by 32 pixels. 2002-11-11 23:34 const_k * Makefile: Extra .vnc files have been removed, having just index.vnc should be enough. 2002-11-11 23:33 const_k * hextile.vnc, index.html, index.vnc, noshared.vnc, shared.vnc, tight.vnc, zlib.vnc: Extra .vnc files have been removed, having just index.vnc should be enough. Also, an example HTML page has been prepared, to simplify installation under a standalone Web server. 2002-11-11 23:13 const_k * README: Documented three ways to use the Java viewer, in the Installation section. 2002-11-07 05:12 const_k * VncCanvas.java, VncViewer.java: Minor change to preserve keyboard focus in VncCanvas after resizing the frame, when running in a separate window. 2002-11-06 08:49 const_k * Makefile, README, ReloginPanel.java, VncViewer.java: Implemented new buttons "Login again" and "Close window" near the disconnect or error messages in the applet mode, and introduced new "Offer Relogin" parameter to control this improvement. Thanks to Peter Astrand for the initial version of the "Login again" patch. 2002-10-29 10:26 const_k * VncCanvas.java: Don't defer update requests if there is some data to receive, or if the last update included a PointerPos message. 2002-10-29 09:06 const_k * HTTPConnectSocket.java, HTTPConnectSocketFactory.java, Makefile: Support for connections via HTTP proxies using HTTP CONNECT method. Most likely, this will not work in applet mode, due to security restrictions in JVMs. 2002-10-29 09:03 const_k * OptionsFrame.java, RfbProto.java, VncCanvas.java: Added support for new CursorPos pseudo-encoding which allows to transmit pointer position from server to clients. 2002-09-24 14:29 const_k * RecordingFrame.java: A patch from Harmen van der Wal -- "a workaround for AFAIK a rare (Blackdown 1.1.7) SecurityManager.checkPropertyAccess() bug, that would otherwise be fatal for an unprivileged applet". 2002-09-24 14:23 const_k * RfbProto.java, VncViewer.java: Enhancements to the exception handling mechanisms, a patch from Harmen van der Wal. 2002-09-24 14:01 const_k * Makefile, README, RfbProto.java, SocketFactory.java, VncViewer.java: A patch from Harmen van der Wal, which makes it easy to plug-in alternative transport methods to the viewer. It can be useful for for things like HTTP tunneling, SSL support, or perhaps for integration with "zebedee", ssh or other tunneling mechanisms. 2002-09-23 18:52 const_k * VncCanvas.java: Reducing max frame size by 30 pixels in each direction, to leave some place on the screen, e.g. for the menu bar on Macintosh or the task bar on Windows; a patch from Steve Kann. 2002-08-27 05:23 const_k * README: Version string changed, version 1.2.6. 2002-08-04 09:39 const * README, RfbProto.java, VncCanvas.java: Version string changed, version 1.2.5. Copyrights updated. 2002-07-05 01:37 const * RfbProto.java, VncCanvas.java, VncViewer.java: More robust and correct methods to determine if Zlib- or Tight-encoded data should be saved Raw-encoded or re-compressed in recorded sessions. Also, always emit warnings in the Java console if such recoding was necessary. 2002-07-05 01:26 const * README: Minor documentation addition. 2002-07-04 23:17 const * OptionsFrame.java: JPEG quality setting should be enabled in the Options frame only in the 24-bit color mode. 2002-07-04 23:02 const * OptionsFrame.java: Unused temporary hack was removed. 2002-07-03 13:25 const * README: Some documentation on RFB session recording. 2002-07-03 12:43 const * RfbProto.java: Forgot to remove debugging output. 2002-07-03 12:38 const * RfbProto.java, VncCanvas.java: Re-compressing Tight-encoded rectangles when recorded session starts after the connection was established, to make it possible to decompress the data without knowing prior pixel data. 2002-07-03 07:11 const * VncViewer.java, RfbProto.java, VncCanvas.java: Special handling of Zlib-encoded rectangles -- they are written either Zlib-encoded if it's a beginning of RFB session, or Raw encoded otherwise. This is needed to make sure it will be possible to decode saved data without knowing the state of zlib compression stream used by the encoder. 2002-07-03 03:49 const * ButtonPanel.java, RecordingFrame.java, VncViewer.java: The "Record" button now appears only if current SecurityManager allows access to the local filesystem. Exceptions after an intentional disconnect are not shown in the applet panel or window any more. 2002-07-03 02:40 const * RecordingFrame.java, RfbProto.java, VncCanvas.java, VncViewer.java: Implement dynamic toggling of session recording. 2002-07-02 23:34 const * VncViewer.java: Preparing to implement dynamic toggling of session recording. The "Save Session" parameter was removed. 2002-06-30 22:44 const * RecordingFrame.java: Fixed copyright string. 2002-06-12 11:45 const * ButtonPanel.java, RecordingFrame.java, VncViewer.java: A simple hack to make the RecordingFrame work, at least when the recording is being turned on before making the connection. The RecordingFrame is still not very useful but at least does allow to record a whole session in one file. 2002-06-12 05:03 const * ButtonPanel.java, Makefile, RecordingFrame.java, VncViewer.java: Added new "Record" button and a GUI to control recording of sessions in FBS files. 2002-06-04 11:01 const * Makefile, OptionsFrame.java, RfbProto.java, SessionRecorder.java, VncCanvas.java, VncViewer.java: Implemented experimental feature to save RFB sessions in FBS files compatible with rfbproxy, and the new "Save Session" parameter where a user can set a file name. Color format requested from the server was changed to little-endian to make saved sessions similar to ones written by the VNC Reflector, and to make colors compatible with RFB Session Player. 2002-06-03 22:55 const * VncCanvas.java: Cleanups in "throws" statements. 2002-06-03 22:50 const * VncCanvas.java: Minor cleanup in comment. 2002-06-03 22:37 const * VncCanvas.java: Major Code cleanup: each decoder was moved from the processNormalProtocol() method to a separate function. 2002-06-03 22:19 const * README: Minor cleanup. 2002-05-23 09:58 const * README, VncViewer.java: New "ENCPASSWORD" parameter, modified patch from Peter Astrand. 2002-05-19 01:03 const * RfbProto.java, VncCanvas.java, VncViewer.java: Throwing Exception instead of IOException if that was not an I/O error. 2002-05-18 23:38 const * RfbProto.java: Applied patch from Peter Astrand to fix problems with Swedish keys and broken JVMs. 2002-04-25 04:51 const * README: Updated version strings for version 1.2.4. 2002-04-25 04:49 const * README: Documented new feature to refresh remote desktop in the view-only mode using "R"/"r" keys. 2002-04-23 06:02 const * ButtonPanel.java: Bugfix: keyboard focus could be set incorrectly. It was returned to desktop even when windows such as Options or Clipboard were created. This looked like new windows had appeared behind the authenticator or desktop window, if the viewer itself was running in a separate window. 2002-04-09 12:10 const * VncViewer.java: Minor bugfix to prevent the "Refresh" button to disappear after the "Disconnect" button changes to "Hide desktop". 2002-04-09 12:05 const * VncViewer.java: Previous bugfix was broken. 2002-04-09 12:01 const * VncViewer.java: Minor bugfix to prevent dumping exceptions on pressing "R"/"r" keys over disconnected desktop. 2002-04-09 11:53 const * VncCanvas.java: Now "R"/"r" keys can be used to request screen updates in view-only mode. 2002-04-08 12:17 const * README: "Show offline desktop" parameter documented. 2002-04-08 12:12 const * OptionsFrame.java, VncCanvas.java, VncViewer.java: "Show Controls" setting moved from OptionsFrame to VncViewer class. 2002-04-08 12:04 const * ButtonPanel.java, VncViewer.java: New "Show Offline Desktop" parameter allowing the disktop to be still displayed even after the remote side closed connection. 2002-04-02 09:12 const * AuthPanel.java: Disabling the password input field on activating connections. 2002-04-02 07:38 const * VncViewer.java: Reporting more meaningful messages on errors. 2002-03-25 07:41 const * VncViewer.java: A cosmetic change. 2002-03-07 09:27 const * VncCanvas.java: Fixed bug causing NullPointerException in view-only mode with disabled button panel. 2002-02-14 07:20 const * ButtonPanel.java, VncCanvas.java: Made the "Ctrl-Alt-Del" button disabled in the view-only mode. 2002-02-14 07:19 const * VncViewer.java: Removed calls printing debugging output. 2002-02-12 15:02 const * README, VncCanvas.java, VncViewer.java: Added new parameters "Defer screen updates", "Defer cursor updates", "Defer update requests", documented in README. 2002-02-12 13:03 const * VncCanvas.java: Made "Restricted colors" option dynamic. 2002-02-12 12:36 const * VncCanvas.java, VncViewer.java: Code cleanups, preparing to make "Restricted colors" option dynamic. 2002-02-12 09:32 const * ButtonPanel.java, OptionsFrame.java, README, RfbProto.java, VncCanvas.java, VncViewer.java: Documented applet parameters, updated copyright strings. 2002-02-12 05:53 const * VncCanvas.java: Solved all issues with JPEG image loading. Added more comments in the source code. 2002-02-12 04:13 const * OptionsFrame.java, VncCanvas.java: Solved problems with asynchronous JPEG image loading, although the solution is not ideal yet. Now the ImageObserver interface is used only to track loading of JPEG images, and is not used with drawImage() method calls. Draft scaling implementation appeared in previous CVS commit was temporarily removed in this revision. 2002-02-08 04:06 const * OptionsFrame.java, VncCanvas.java: Simple and inefficient scaling implementation, new "Scaling Factor" parameter. 2002-02-07 10:20 const * ButtonPanel.java, VncViewer.java: Preventing authentication retries when the PASSWORD parameter is used. Closing windows and disconnecting on the applet shutdown. Terminating the application properly on closing the authentication window. Packing the window on reporting errors when in a separate window; this is necessary because it's possible that the window was empty. Disconnecting on fatal errors. Always forcing the keyboard focus go to the desktop on activating the connection. Code re-organizations and cleanups e.g. new tryAuthenticate() method. 2002-01-30 10:25 const * VncCanvas.java: The frame size now should be limited by the screen size. JPEG support improved, but drawing is still not reliable. Minor code cleanups -- methods re-arranged. 2002-01-30 10:22 const * OptionsFrame.java: A small piece of debugging code removed. 2002-01-30 05:47 const * OptionsFrame.java, RfbProto.java, VncCanvas.java: Drawing model was changed again; now usual off-screen Image is used for double-buffering instead of MemoryImageSource. Preliminary implementation of JPEG support in the Tight decoder. New "JPEG image quality" parameter and corresponding item in the Options frame. 2002-01-24 22:49 const * VncCanvas.java: Bugfixes in the Tight decoder: recent changes broke 8-bit color mode. Bugfixes in the XCursor encoding support: cursor colors were interpreted incorrectly. 2002-01-14 13:11 const * VncCanvas.java: 24-bit Tight decoder finished. Now it parses 24-bit (not 32-bit!) color samples correctly, and is able to decode data pre-processed with the "Gradient" filter. 2002-01-14 10:46 const * VncCanvas.java: Preliminary working support for 24-bit colors in the Tight decoder. 2002-01-14 06:00 const * OptionsFrame.java: Color format was not set correctly. 2002-01-14 05:32 const * RfbProto.java, VncCanvas.java: Code cleanups: changes in rfb.is.read() and rfb.is.readFully() calls. 2002-01-14 05:18 const * AuthPanel.java, VncCanvas.java, VncViewer.java: Support for 24-bit color in RichCursor encoding. 2002-01-12 16:11 const * OptionsFrame.java, VncCanvas.java: Support for 24-bit colors. At this moment, all decoders support this color mode, with two exceptions of Tight and RichCursor. 2002-01-12 15:57 const * RfbProto.java: Removed a piece of code used for debugging. 2002-01-12 10:23 const * OptionsFrame.java, RfbProto.java, VncCanvas.java: The "View Only" mode now can be turned on/off at any moment. 2002-01-12 08:12 const * RfbProto.java: Insert key now can be passed to the remote side. 2002-01-12 06:32 const * VncCanvas.java, VncViewer.java: Dramatically simplified and robust implementation of handling XCursor/RichCursor encodings. Enhancements and bugfixes for the "Open New Window" mode. Other minor enhancements and code cleanups. 2002-01-11 10:36 const * ClipboardFrame.java, OptionsFrame.java: Minor code enhancements. 2002-01-11 09:35 const * VncCanvas.java, VncViewer.java: Implemented scrolling of the desktop area, when the desktop is shown in a separate window. 2002-01-11 04:51 const * ClipboardFrame.java, OptionsFrame.java: "Dismiss" buttons renamed to "Close". 2002-01-10 14:19 const * ButtonPanel.java, VncViewer.java: Changes in the button panel. Now keyboard focus moves back to the authentication panel or to the desktop after pressing any button on the panel. Additionally, keyboard focus should move to the desktop automatically when VNC connection is established. 2002-01-10 13:53 const * ButtonPanel.java: Implemented new "Refresh" button. Pressing it results sending a non-incremental FramebufferUpdateRequest message to the server. 2002-01-10 13:51 const * VncCanvas.java: Now the viewer adjusts its desktop/window size on desktop size changes on the remote side (working support for NewFBSize pseudo-encoding). 2002-01-10 12:50 const * AuthPanel.java, ButtonPanel.java, ClipboardFrame.java, Makefile, OptionsFrame.java, RfbProto.java, VncCanvas.java, VncViewer.java, authenticationPanel.java, clipboardFrame.java, dir.mk, hextile.vnc, index.vnc, noshared.vnc, optionsFrame.java, rfbProto.java, shared.vnc, tight.vnc, vncCanvas.java, vncviewer.java, zlib.vnc: New "Open New Window" parameter was implemented, now the viewer can work in a separate frame instead of running in the applet area. Class names were capitalized, to reflect usual Java naming standards. 2002-01-10 10:22 const * hextile.vnc, index.vnc, noshared.vnc, shared.vnc, tight.vnc, zlib.vnc: Inserted a
tag to prevent www.tightvnc.com link appear to the left of the applet area. 2001-12-17 13:32 const * vncviewer.java: In application mode, terminate application on window close event. 2001-12-17 12:28 const * vncCanvas.java: Performance fixes in CopyRect routine, and the FillLargeArea method. 2001-12-17 11:39 const * ButtonPanel.java, Makefile, dir.mk, rfbProto.java, vncCanvas.java, vncviewer.java: Converted to Java 1.1 event model. 2001-12-16 13:49 const * vncCanvas.java: Got rid of calls to deprecated methods etc. 2001-12-16 13:37 const * vncviewer.java: Minor code cleanups. 2001-12-16 13:37 const * authenticationPanel.java: Converted to Java 1.1 event model. 2001-12-16 12:51 const * optionsFrame.java: Converted to Java 1.1 event model. 2001-12-16 12:19 const * clipboardFrame.java: Converted to Java 1.1 event model. 2001-12-16 10:17 const * clipboardFrame.java: Removed debugging code forgotten in the previous version. Minor code cleanups and formating changes. 2001-12-16 10:00 const * authenticationPanel.java, clipboardFrame.java, optionsFrame.java, rfbProto.java, vncviewer.java: Got rid of most calls to methods deprecated in Java 1.1. 2001-12-16 07:41 const * vncCanvas.java: Beeping through java.awt.Toolkit on receiving Bell RFB message. 2001-12-16 07:33 const * vncCanvas.java: Drawing techniques have been changed: now all the painting is performed in update() and paint() methods of the Canvas component. This should solve painting problems under some JVM implementations. 2001-12-16 06:56 const * Makefile, animatedMemoryImageSource.java, dir.mk, vncCanvas.java: First step of converting the source to Java 1.1: got rid of animatedMemoryImageSource class; using new setAnimated() method in the standard MemoryImageSource class instead. 2001-09-16 00:06 const * optionsFrame.java, rfbProto.java, vncCanvas.java, vncviewer.java: Addition of new parameters PASSWORD, "Include Controls", and "View Only", modified patch from Steve Kann. 2001-06-18 09:46 const * README: Version string change. 2001-05-12 02:55 const * vncviewer.java: (setEncodings): Possible NullPointerException fixed. 2001-03-07 00:06 const * vncCanvas.java: Initial "software cursor" position set to (0, 0) instead of (40, 40). Minor code clean-up. 2001-02-15 14:45 const * vncCanvas.java: Minor performance fix and tiny clean-ups in code and comments. 2001-02-15 13:29 const * clipboardFrame.java, optionsFrame.java: Tiny changes after looking in the TridiaVNC CVS sources. 2001-02-15 12:48 const * README: Version string changed. 2001-02-15 09:48 const * vncCanvas.java: A number of performance optimizations and code clean-ups for all supported encodings. 2001-02-14 11:56 const * optionsFrame.java, vncCanvas.java: Drawing techniques changed: now all drawing is performed through the rawPixelsImage object and the pixels[] array, paintImage is not used any more. Settings "Raw pixel drawing: Fast/Reliable" and "CopyRect: Fast/Reliable" removed from the Options panel since they do not make sense in new drawing model. Currently drawing of solid-color areas is slow but this issue hopefully will be fixed in next versions. 2001-02-07 17:06 const * rfbProto.java, vncCanvas.java, vncviewer.java: Fixes for compilation on Java 2 platform, from Klaus Erber. 2001-01-28 02:58 const * README, optionsFrame.java, rfbProto.java, vncCanvas.java: One more name added to copyright strings. ;-) 2001-01-28 02:51 const * hextile.vnc, index.vnc, noshared.vnc, shared.vnc, tight.vnc, zlib.vnc: www.TridiaVNC.com links chanded to www.TightVNC.com. 2001-01-28 02:43 const * Makefile, hextile.vnc, noshared.vnc, tight.vnc: More HTML templates for different default settings prepared. 2001-01-28 02:36 const * optionsFrame.java: Tight encoding is now set by default. 2001-01-26 14:24 const * vncviewer.java: Tiny formatting changes. 2001-01-26 13:11 const * authenticationPanel.java, vncviewer.java: From TridiaVNC: set initial input focus to password field. 2001-01-26 12:58 const * Makefile: Unneeded changes reverted. 2001-01-26 10:52 const * vncCanvas.java: Many changes. Cursor shape updates should work in all modes. 2001-01-25 11:31 const * optionsFrame.java, rfbProto.java, vncCanvas.java: Support for EncodingLastRect added. Bugfix: "Cursor shape updates: Ignore" option caused exceptions on XCursor updates. 2001-01-25 11:10 const * optionsFrame.java, vncCanvas.java, vncviewer.java: RichCursor and XCursor encodings now work, but only for raw encoding. Minor formatting fixes (spaces -> tabs). 2001-01-25 11:09 const * rfbProto.java: Minor formatting fixes (spaces -> tabs). 2001-01-24 10:25 const * vncCanvas.java: "Cursor shape updates: Ignore" option works for RichCursor encoding. 2001-01-24 09:55 const * optionsFrame.java, vncCanvas.java: Non-finished RichCursor support, minor code cleanups. 2001-01-23 09:42 const * optionsFrame.java, rfbProto.java: "Cursor shape updates" item in options frame. Minor bugfix: "Compression level" item remained enabled when raw encoding was chosen after zlib or tight. 2001-01-23 08:02 const * optionsFrame.java, rfbProto.java: Requesting compression level for tight and zlib encodings. 2001-01-22 09:22 const * vncCanvas.java: Major speed optimizations and code cleanups in tight encoding implementation. 2001-01-22 06:10 const * vncCanvas.java: More error checking. 2001-01-22 06:06 const * vncCanvas.java: Error checking, code cleanups. 2001-01-18 22:53 const * Makefile, optionsFrame.java, rfbProto.java, vncCanvas.java: First version of Java vncviewer with tight encoding support. 2000-09-29 08:39 const * DesCipher.java, LICENCE.TXT, Makefile, README, animatedMemoryImageSource.java, authenticationPanel.java, clipboardFrame.java, dir.mk, index.vnc, optionsFrame.java, rfbProto.java, shared.vnc, vncCanvas.java, vncviewer.java, zlib.vnc: Initial revision tightvnc-java-1.2.7.orig/OptionsFrame.java0100644000076500007650000002526107557537526017556 0ustar olaluolalu// // Copyright (C) 2001 HorizonLive.com, Inc. All Rights Reserved. // Copyright (C) 2001 Constantin Kaplinsky. All Rights Reserved. // Copyright (C) 2000 Tridia Corporation. All Rights Reserved. // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // Options frame. // // This deals with all the options the user can play with. // It sets the encodings array and some booleans. // import java.awt.*; import java.awt.event.*; class OptionsFrame extends Frame implements WindowListener, ActionListener, ItemListener { static String[] names = { "Encoding", "Compression level", "JPEG image quality", "Cursor shape updates", "Use CopyRect", "Restricted colors", "Mouse buttons 2 and 3", "View only", "Share desktop", }; static String[][] values = { { "Raw", "RRE", "CoRRE", "Hextile", "Zlib", "Tight" }, { "Default", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, { "JPEG off", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, { "Enable", "Ignore", "Disable" }, { "Yes", "No" }, { "Yes", "No" }, { "Normal", "Reversed" }, { "Yes", "No" }, { "Yes", "No" }, }; final int encodingIndex = 0, compressLevelIndex = 1, jpegQualityIndex = 2, cursorUpdatesIndex = 3, useCopyRectIndex = 4, eightBitColorsIndex = 5, mouseButtonIndex = 6, viewOnlyIndex = 7, shareDesktopIndex = 8; Label[] labels = new Label[names.length]; Choice[] choices = new Choice[names.length]; Button closeButton; VncViewer viewer; // // The actual data which other classes look at: // int[] encodings = new int[20]; int nEncodings; int compressLevel; int jpegQuality; boolean eightBitColors; boolean requestCursorUpdates; boolean ignoreCursorUpdates; boolean reverseMouseButtons2And3; boolean shareDesktop; boolean viewOnly; // // Constructor. Set up the labels and choices from the names and values // arrays. // OptionsFrame(VncViewer v) { super("TightVNC Options"); viewer = v; GridBagLayout gridbag = new GridBagLayout(); setLayout(gridbag); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.BOTH; for (int i = 0; i < names.length; i++) { labels[i] = new Label(names[i]); gbc.gridwidth = 1; gridbag.setConstraints(labels[i],gbc); add(labels[i]); choices[i] = new Choice(); gbc.gridwidth = GridBagConstraints.REMAINDER; gridbag.setConstraints(choices[i],gbc); add(choices[i]); choices[i].addItemListener(this); for (int j = 0; j < values[i].length; j++) { choices[i].addItem(values[i][j]); } } closeButton = new Button("Close"); gbc.gridwidth = GridBagConstraints.REMAINDER; gridbag.setConstraints(closeButton, gbc); add(closeButton); closeButton.addActionListener(this); pack(); addWindowListener(this); // Set up defaults choices[encodingIndex].select("Tight"); choices[compressLevelIndex].select("Default"); choices[jpegQualityIndex].select("6"); choices[cursorUpdatesIndex].select("Enable"); choices[useCopyRectIndex].select("Yes"); choices[eightBitColorsIndex].select("No"); choices[mouseButtonIndex].select("Normal"); choices[viewOnlyIndex].select("No"); choices[shareDesktopIndex].select("Yes"); // But let them be overridden by parameters for (int i = 0; i < names.length; i++) { String s = viewer.readParameter(names[i], false); if (s != null) { for (int j = 0; j < values[i].length; j++) { if (s.equalsIgnoreCase(values[i][j])) { choices[i].select(j); } } } } // Make the booleans and encodings array correspond to the state of the GUI setEncodings(); setColorFormat(); setOtherOptions(); } // // Disable the shareDesktop option // void disableShareDesktop() { labels[shareDesktopIndex].setEnabled(false); choices[shareDesktopIndex].setEnabled(false); } // // setEncodings looks at the encoding, compression level, JPEG // quality level, cursor shape updates and copyRect choices and sets // the encodings array appropriately. It also calls the VncViewer's // setEncodings method to send a message to the RFB server if // necessary. // void setEncodings() { nEncodings = 0; if (choices[useCopyRectIndex].getSelectedItem().equals("Yes")) { encodings[nEncodings++] = RfbProto.EncodingCopyRect; } int preferredEncoding = RfbProto.EncodingRaw; boolean enableCompressLevel = false; if (choices[encodingIndex].getSelectedItem().equals("RRE")) { preferredEncoding = RfbProto.EncodingRRE; } else if (choices[encodingIndex].getSelectedItem().equals("CoRRE")) { preferredEncoding = RfbProto.EncodingCoRRE; } else if (choices[encodingIndex].getSelectedItem().equals("Hextile")) { preferredEncoding = RfbProto.EncodingHextile; } else if (choices[encodingIndex].getSelectedItem().equals("Zlib")) { preferredEncoding = RfbProto.EncodingZlib; enableCompressLevel = true; } else if (choices[encodingIndex].getSelectedItem().equals("Tight")) { preferredEncoding = RfbProto.EncodingTight; enableCompressLevel = true; } encodings[nEncodings++] = preferredEncoding; if (preferredEncoding != RfbProto.EncodingHextile) { encodings[nEncodings++] = RfbProto.EncodingHextile; } if (preferredEncoding != RfbProto.EncodingTight) { encodings[nEncodings++] = RfbProto.EncodingTight; } if (preferredEncoding != RfbProto.EncodingZlib) { encodings[nEncodings++] = RfbProto.EncodingZlib; } if (preferredEncoding != RfbProto.EncodingCoRRE) { encodings[nEncodings++] = RfbProto.EncodingCoRRE; } if (preferredEncoding != RfbProto.EncodingRRE) { encodings[nEncodings++] = RfbProto.EncodingRRE; } // Handle compression level setting. if (enableCompressLevel) { labels[compressLevelIndex].setEnabled(true); choices[compressLevelIndex].setEnabled(true); try { compressLevel = Integer.parseInt(choices[compressLevelIndex].getSelectedItem()); } catch (NumberFormatException e) { compressLevel = -1; } if (compressLevel >= 1 && compressLevel <= 9) { encodings[nEncodings++] = RfbProto.EncodingCompressLevel0 + compressLevel; } else { compressLevel = -1; } } else { labels[compressLevelIndex].setEnabled(false); choices[compressLevelIndex].setEnabled(false); } // Handle JPEG quality setting. if (preferredEncoding == RfbProto.EncodingTight && !eightBitColors) { labels[jpegQualityIndex].setEnabled(true); choices[jpegQualityIndex].setEnabled(true); try { jpegQuality = Integer.parseInt(choices[jpegQualityIndex].getSelectedItem()); } catch (NumberFormatException e) { jpegQuality = -1; } if (jpegQuality >= 0 && jpegQuality <= 9) { encodings[nEncodings++] = RfbProto.EncodingQualityLevel0 + jpegQuality; } else { jpegQuality = -1; } } else { labels[jpegQualityIndex].setEnabled(false); choices[jpegQualityIndex].setEnabled(false); } // Request cursor shape updates if necessary. requestCursorUpdates = !choices[cursorUpdatesIndex].getSelectedItem().equals("Disable"); if (requestCursorUpdates) { encodings[nEncodings++] = RfbProto.EncodingXCursor; encodings[nEncodings++] = RfbProto.EncodingRichCursor; ignoreCursorUpdates = choices[cursorUpdatesIndex].getSelectedItem().equals("Ignore"); if (!ignoreCursorUpdates) encodings[nEncodings++] = RfbProto.EncodingPointerPos; } encodings[nEncodings++] = RfbProto.EncodingLastRect; encodings[nEncodings++] = RfbProto.EncodingNewFBSize; viewer.setEncodings(); } // // setColorFormat sets eightBitColors variable depending on the GUI // setting, causing switches between 8-bit and 24-bit colors mode if // necessary. // void setColorFormat() { eightBitColors = choices[eightBitColorsIndex].getSelectedItem().equals("Yes"); boolean enableJPEG = !eightBitColors && choices[encodingIndex].getSelectedItem().equals("Tight"); labels[jpegQualityIndex].setEnabled(enableJPEG); choices[jpegQualityIndex].setEnabled(enableJPEG); } // // setOtherOptions looks at the "other" choices (ones which don't set the // encoding or the color format) and sets the boolean flags appropriately. // void setOtherOptions() { reverseMouseButtons2And3 = choices[mouseButtonIndex].getSelectedItem().equals("Reversed"); viewOnly = choices[viewOnlyIndex].getSelectedItem().equals("Yes"); if (viewer.vc != null) viewer.vc.enableInput(!viewOnly); shareDesktop = choices[shareDesktopIndex].getSelectedItem().equals("Yes"); } // // Respond to actions on Choice controls // public void itemStateChanged(ItemEvent evt) { Object source = evt.getSource(); if (source == choices[encodingIndex] || source == choices[compressLevelIndex] || source == choices[jpegQualityIndex] || source == choices[cursorUpdatesIndex] || source == choices[useCopyRectIndex]) { setEncodings(); } else if (source == choices[eightBitColorsIndex]) { setColorFormat(); } else if (source == choices[mouseButtonIndex] || source == choices[shareDesktopIndex] || source == choices[viewOnlyIndex]) { setOtherOptions(); } } // // Respond to button press // public void actionPerformed(ActionEvent evt) { if (evt.getSource() == closeButton) setVisible(false); } // // Respond to window events // public void windowClosing(WindowEvent evt) { setVisible(false); } public void windowActivated(WindowEvent evt) {} public void windowDeactivated(WindowEvent evt) {} public void windowOpened(WindowEvent evt) {} public void windowClosed(WindowEvent evt) {} public void windowIconified(WindowEvent evt) {} public void windowDeiconified(WindowEvent evt) {} } tightvnc-java-1.2.7.orig/ReloginPanel.java0100644000076500007650000000363307562244020017502 0ustar olaluolalu// // Copyright (C) 2002 Cendio Systems. All Rights Reserved. // Copyright (C) 2002 Constantin Kaplinsky. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // ReloginPanel class implements panel with a button for logging in again, // after fatal errors or disconnect // import java.awt.*; import java.awt.event.*; import java.applet.*; // // The panel which implements the Relogin button // class ReloginPanel extends Panel implements ActionListener { Button reloginButton; Button closeButton; VncViewer viewer; // // Constructor. // public ReloginPanel(VncViewer v) { viewer = v; setLayout(new FlowLayout(FlowLayout.CENTER)); reloginButton = new Button("Login again"); add(reloginButton); reloginButton.addActionListener(this); if (viewer.inSeparateFrame) { closeButton = new Button("Close window"); add(closeButton); closeButton.addActionListener(this); } } // // This method is called when a button is pressed. // public synchronized void actionPerformed(ActionEvent evt) { if (viewer.inSeparateFrame) viewer.vncFrame.dispose(); if (evt.getSource() == reloginButton) viewer.getAppletContext().showDocument(viewer.getDocumentBase()); } } tightvnc-java-1.2.7.orig/HTTPConnectSocket.java0100644000076500007650000000360007557537775020411 0ustar olaluolalu// // Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // // HTTPConnectSocket.java together with HTTPConnectSocketFactory.java // implement an alternate way to connect to VNC servers via one or two // HTTP proxies supporting the HTTP CONNECT method. // import java.net.*; import java.io.*; class HTTPConnectSocket extends Socket { public HTTPConnectSocket(String host, int port, String proxyHost, int proxyPort) throws IOException { // Connect to the specified HTTP proxy super(proxyHost, proxyPort); // Send the CONNECT request getOutputStream().write(("CONNECT " + host + ":" + port + " HTTP/1.0\r\n\r\n").getBytes()); // Read the first line of the response DataInputStream is = new DataInputStream(getInputStream()); String str = is.readLine(); // Check the HTTP error code -- it should be "200" on success if (!str.startsWith("HTTP/1.0 200 ")) { if (str.startsWith("HTTP/1.0 ")) str = str.substring(9); throw new IOException("Proxy reports \"" + str + "\""); } // Success -- skip remaining HTTP headers do { str = is.readLine(); } while (str.length() != 0); } }