The shipped VncThumbnailViewerWin1.4.2.exe is a native launcher stub with a Java JAR appended. This commit adds: - src/: full Java source recovered from the bundled .class files (CFR), plus src/summary.txt with decompiler caveats - ANALYSIS.md: architecture, data flow, hosts-file format, and security notes - build-app-image.ps1: reproducible jpackage build that repackages the original classes and bundles a slim jlinked runtime (java.base + java.desktop) into a self-contained native app-image (no Java required on the target) The 74 MB app-image is shipped as a release asset rather than tracked. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
108 lines
4.1 KiB
Java
108 lines
4.1 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*/
|
|
import java.awt.Button;
|
|
import java.awt.Component;
|
|
import java.awt.FlowLayout;
|
|
import java.awt.Panel;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.KeyEvent;
|
|
import java.io.IOException;
|
|
|
|
class ButtonPanel
|
|
extends Panel
|
|
implements ActionListener {
|
|
VncViewer viewer;
|
|
Button disconnectButton;
|
|
Button optionsButton;
|
|
Button recordButton;
|
|
Button clipboardButton;
|
|
Button ctrlAltDelButton;
|
|
Button refreshButton;
|
|
|
|
ButtonPanel(VncViewer vncViewer) {
|
|
this.viewer = vncViewer;
|
|
this.setLayout(new FlowLayout(0, 0, 0));
|
|
this.disconnectButton = new Button("Disconnect");
|
|
this.disconnectButton.setEnabled(false);
|
|
this.add(this.disconnectButton);
|
|
this.disconnectButton.addActionListener(this);
|
|
this.optionsButton = new Button("Options");
|
|
this.add(this.optionsButton);
|
|
this.optionsButton.addActionListener(this);
|
|
this.clipboardButton = new Button("Clipboard");
|
|
this.clipboardButton.setEnabled(false);
|
|
this.add(this.clipboardButton);
|
|
this.clipboardButton.addActionListener(this);
|
|
if (this.viewer.rec != null) {
|
|
this.recordButton = new Button("Record");
|
|
this.add(this.recordButton);
|
|
this.recordButton.addActionListener(this);
|
|
}
|
|
this.ctrlAltDelButton = new Button("Send Ctrl-Alt-Del");
|
|
this.ctrlAltDelButton.setEnabled(false);
|
|
this.add(this.ctrlAltDelButton);
|
|
this.ctrlAltDelButton.addActionListener(this);
|
|
this.refreshButton = new Button("Refresh");
|
|
this.refreshButton.setEnabled(false);
|
|
this.add(this.refreshButton);
|
|
this.refreshButton.addActionListener(this);
|
|
}
|
|
|
|
public void enableButtons() {
|
|
this.disconnectButton.setEnabled(true);
|
|
this.clipboardButton.setEnabled(true);
|
|
this.refreshButton.setEnabled(true);
|
|
}
|
|
|
|
public void disableButtonsOnDisconnect() {
|
|
this.remove(this.disconnectButton);
|
|
this.disconnectButton = new Button("Hide desktop");
|
|
this.disconnectButton.setEnabled(true);
|
|
this.add((Component)this.disconnectButton, 0);
|
|
this.disconnectButton.addActionListener(this);
|
|
this.optionsButton.setEnabled(false);
|
|
this.clipboardButton.setEnabled(false);
|
|
this.ctrlAltDelButton.setEnabled(false);
|
|
this.refreshButton.setEnabled(false);
|
|
this.validate();
|
|
}
|
|
|
|
public void enableRemoteAccessControls(boolean bl) {
|
|
this.ctrlAltDelButton.setEnabled(bl);
|
|
}
|
|
|
|
public void actionPerformed(ActionEvent actionEvent) {
|
|
this.viewer.moveFocusToDesktop();
|
|
if (actionEvent.getSource() == this.disconnectButton) {
|
|
this.viewer.disconnect();
|
|
} else if (actionEvent.getSource() == this.optionsButton) {
|
|
((Component)this.viewer.options).setVisible(!this.viewer.options.isVisible());
|
|
} else if (actionEvent.getSource() == this.recordButton) {
|
|
((Component)this.viewer.rec).setVisible(!this.viewer.rec.isVisible());
|
|
} else if (actionEvent.getSource() == this.clipboardButton) {
|
|
((Component)this.viewer.clipboard).setVisible(!this.viewer.clipboard.isVisible());
|
|
} else if (actionEvent.getSource() == this.ctrlAltDelButton) {
|
|
try {
|
|
KeyEvent keyEvent = new KeyEvent(this, 401, 0L, 10, 127);
|
|
this.viewer.rfb.writeKeyEvent(keyEvent);
|
|
keyEvent = new KeyEvent(this, 402, 0L, 10, 127);
|
|
this.viewer.rfb.writeKeyEvent(keyEvent);
|
|
}
|
|
catch (IOException iOException) {
|
|
iOException.printStackTrace();
|
|
}
|
|
} else if (actionEvent.getSource() == this.refreshButton) {
|
|
try {
|
|
RfbProto rfbProto = this.viewer.rfb;
|
|
rfbProto.writeFramebufferUpdateRequest(0, 0, rfbProto.framebufferWidth, rfbProto.framebufferHeight, false);
|
|
}
|
|
catch (IOException iOException) {
|
|
iOException.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|