Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds colors #175

Merged
merged 21 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified docs/assistant_capture_settings.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/de_settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ <h3><img src="assistant.png" alt="Assistent"/> &nbsp; <a id="assistant" class="n
Hier kann der <em>Assistent</em> definieren, wie der Bildschirm des <em>Assistierten</em>
<strong>erfasst</strong> werden soll; Es kann sowohl der Intervall (in Millisekunden) zwischen
zwei Aufnahmen (Tick), als auch die Anzahl Graustufen definiert werden.
Beginnend mit Dayon! 15, können alternativ auch sRGB-Farben verwendet werden. In diesem Fall wird die Anzahl der Graustufen ignoriert.
Bitte beachten Sie, dass bei der Verwendung von "Farben" mehr Bandbreite und RAM auf der <em>Assistierten</em> Seite verbraucht wird.
</p>

<p>
Expand Down
2 changes: 2 additions & 0 deletions docs/fr_settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ <h3><img src="assistant.png" alt="Assistant"/> &nbsp;<a id="assistant-details" c
Cette forme vous permet de configurer la façon dont l'écran est <strong>capturé</strong> ; vous pouvez configurer
l'interval de temps (en milliseconde) entre deux captures (aka. tic-tac) ainsi que le nombre de niveaux de gris.
Moins de niveaux veut dire moins d'information à transmettre sur le réseau (au détriment de la qualité des images).
À partir de Dayon ! 15, les couleurs sRGB peuvent également être utilisées comme alternative. Dans ce cas, le nombre de niveaux de gris est ignoré.
Veuillez noter que l'utilisation des "Couleurs réelles" consomme plus de bande passante et plus de RAM du côté de l'<em>assisté</em>.
</p>

<p>
Expand Down
2 changes: 2 additions & 0 deletions docs/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ <h3><img src="assistant.png" alt="Assistant"/> &nbsp; <a id="assistant" class="n
<p>
Use that form to set up how the <em>assisted</em> screen is going to be <strong>captured</strong>; you can
configure the time (in milliseconds) between two captures (aka. tick) as well as the number of gray levels.
Starting with Dayon! 15, also sRGB colors can be used. In that case, the number of gray levels are ignored.
Please note that the use of "True colors" consumes more bandwidth and uses more RAM on the <em>assisted</em> side.
</p>

<p>
Expand Down
2 changes: 2 additions & 0 deletions docs/sv_settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ <h3><img src="assistant.png" alt="Hjälpgivare"/> &nbsp;<a id="assistant-details

<p>
Använd formuläret för att ange hur <em>hjälptagarens</em> skärm blir <strong>avläst</strong>; du kan anpassa (i millisekunder) tiden mellan två avläsningar (eller "tick") liksom antal gråskalor i bilden.
Från och med Dayon! 15 kan sRGB-färger också användas som ett alternativ. I detta fall ignoreras antalet gråtoner.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lammel-hub may I ask you to have a brief look at the Swedish grammar please?

  • sv_settings.html
  • Babylon_sv.properties

Very appreciated, many thanks in advance!

Observera att användningen av "Sanna färger" förbrukar mer bandbredd och mer RAM på <em>hjälpgivare</em>-sidan.
</p>

<p>
Expand Down
2 changes: 2 additions & 0 deletions docs/zh_settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ <h3><img src="assistant.png" alt="Assistant"/> &nbsp; <a id="assistant" class="n

<p>
&nbsp; &nbsp; 使用这个表单来设置屏幕捕获;您可以配置两次<strong> 屏幕捕获 </strong>(又名时钟滴答,即tick)之间的时间(以毫秒为单位)和灰度级数。
从 Dayon 开始!15 开始,也可以使用 sRGB 颜色作为替代。在这种情况下,灰度级数将被忽略。
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rmshadows may I ask you to have a brief look at the Chinese grammar please?

zh_settings.html
Babylon_zh.properties

Very appreciated, many thanks in advance!

请注意,使用 "真面目" 会在 <em>Assisted - 用户端</em> 端消耗更多带宽和内存。
</p>

<p>
Expand Down
2 changes: 1 addition & 1 deletion resources/dayon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ elif [ ! -f /etc/alternatives/java ]; then
else
JAVA=$(ls -l /etc/alternatives/java | awk -F'> ' '{print $2}')
fi
JAVA_OPTS="-Xmx256M"
JAVA_OPTS="-Xmx512M"
case "$@" in
*log=console*)
LOG=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ protected void execute() throws IOException {
cache = configuration.useCache() ? new RegularTileCache(configuration.getCacheMaxSize(), configuration.getCachePurgeSize())
: new NullTileCache();

Log.info("De-Compressor engine has been reconfigured [tile:" + message.getId() + "] " + configuration);
Log.info("De-Compressor engine has been reconfigured [tile:" + message.getId() + "]" + configuration);
}

cache.clearHits();
Expand Down
116 changes: 78 additions & 38 deletions src/main/java/mpo/dayon/assistant/gui/Assistant.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import mpo.dayon.common.squeeze.CompressionMethod;
import mpo.dayon.common.network.FileUtilities;
import mpo.dayon.common.utils.Language;
import mpo.dayon.common.version.Version;

import javax.swing.*;
import java.awt.*;
Expand All @@ -46,10 +47,11 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;

import static java.lang.Math.abs;
import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
import static java.lang.Math.*;
import static java.lang.String.format;
import static java.lang.String.valueOf;
import static java.lang.Thread.sleep;
import static javax.swing.SwingConstants.HORIZONTAL;
import static mpo.dayon.common.babylon.Babylon.translate;
import static mpo.dayon.common.gui.common.ImageUtilities.getOrCreateIcon;
Expand Down Expand Up @@ -87,6 +89,8 @@ public class Assistant implements ClipboardOwner {

private final Object prevBufferLOCK = new Object();

private final Object upnpEnabledLOCK = new Object();

private byte[] prevBuffer = null;

private int prevWidth = -1;
Expand Down Expand Up @@ -169,18 +173,6 @@ private void createCounters() {
counters = new ArrayList<>(Arrays.asList(receivedBitCounter, receivedTileCounter, skippedTileCounter, mergedTileCounter, captureCompressionCounter));
}

public boolean isUpnpEnabled() {
while (upnpEnabled == null) {
try {
sleep(10L);
} catch (InterruptedException e) {
Log.warn("Swallowed", e);
Thread.currentThread().interrupt();
}
}
return upnpEnabled;
}

public NetworkAssistantEngine getNetworkEngine() {
return networkEngine;
}
Expand Down Expand Up @@ -369,13 +361,13 @@ public void actionPerformed(ActionEvent ev) {
JFrame captureFrame = (JFrame) SwingUtilities.getRoot((Component) ev.getSource());

final JPanel pane = new JPanel();
pane.setLayout(new GridLayout(2, 2, 10, 10));
pane.setLayout(new GridLayout(3, 2, 10, 10));

final JLabel tickLbl = new JLabel(translate("tick"));
tickLbl.setToolTipText(translate("tick.tooltip"));
final JSlider tickMillisSlider = new JSlider(HORIZONTAL, 50, 1000, captureEngineConfiguration.getCaptureTick());
final Properties tickLabelTable = new Properties(3);
JLabel actualTick = new JLabel(format("%dms", tickMillisSlider.getValue()));
JLabel actualTick = new JLabel(format(" %dms ", tickMillisSlider.getValue()));
tickLabelTable.put(50, new JLabel(translate("min")));
tickLabelTable.put(550, actualTick);
tickLabelTable.put(1000, new JLabel(translate("max")));
Expand All @@ -389,43 +381,54 @@ public void actionPerformed(ActionEvent ev) {
final JLabel grayLevelsLbl = new JLabel(translate("grays"));
final JSlider grayLevelsSlider = new JSlider(HORIZONTAL, 0, 6, 6 - captureEngineConfiguration.getCaptureQuantization().ordinal());
final Properties grayLabelTable = new Properties(3);
JLabel actualLevels = new JLabel(format("%d", toGrayLevel(grayLevelsSlider.getValue()).getLevels()));
grayLabelTable.put(0, new JLabel(translate("min")));
grayLabelTable.put(3, actualLevels);
JLabel actualLevels = new JLabel(format(" %d ", toGrayLevel(grayLevelsSlider.getValue()).getLevels()));
if (!networkConfiguration.isMonochromePeer()) {
grayLabelTable.put(0, new JLabel(translate("min")));
grayLabelTable.put(3, actualLevels);
} else {
grayLabelTable.put(3, new JLabel(translate("min")));
grayLevelsSlider.setMinimum(3);
}
grayLabelTable.put(6, new JLabel(translate("max")));
grayLevelsSlider.setLabelTable(grayLabelTable);
grayLevelsSlider.setMajorTickSpacing(1);
grayLevelsSlider.setPaintTicks(true);
grayLevelsSlider.setPaintLabels(true);
grayLevelsSlider.setSnapToTicks(true);
pane.add(grayLevelsLbl);
pane.add(grayLevelsSlider);
pane.add(grayLevelsLbl).setEnabled(!captureEngineConfiguration.isCaptureColors());
pane.add(grayLevelsSlider).setEnabled(!captureEngineConfiguration.isCaptureColors());

final JLabel colorsLbl = new JLabel(translate("colors"));
final JCheckBox colorsCb = new JCheckBox();
colorsCb.setSelected(captureEngineConfiguration.isCaptureColors());
pane.add(colorsLbl).setEnabled(!networkConfiguration.isMonochromePeer());
pane.add(colorsCb).setEnabled(!networkConfiguration.isMonochromePeer());

tickMillisSlider.addChangeListener(e -> {
actualTick.setText(tickMillisSlider.getValue() < 1000 ? format("%dms", tickMillisSlider.getValue()) : "1s");
if (!tickMillisSlider.getValueIsAdjusting()) {
sendCaptureConfiguration(new CaptureEngineConfiguration(tickMillisSlider.getValue(),
toGrayLevel(grayLevelsSlider.getValue())));
toGrayLevel(grayLevelsSlider.getValue()), captureEngineConfiguration.isCaptureColors()));
}
});
grayLevelsSlider.addChangeListener(e -> {
actualLevels.setText(format("%d", toGrayLevel(grayLevelsSlider.getValue()).getLevels()));
if (!grayLevelsSlider.getValueIsAdjusting()) {
if (!grayLevelsSlider.getValueIsAdjusting() && !captureEngineConfiguration.isCaptureColors()) {
sendCaptureConfiguration(new CaptureEngineConfiguration(tickMillisSlider.getValue(),
toGrayLevel(grayLevelsSlider.getValue())));
toGrayLevel(grayLevelsSlider.getValue()), false));
}
});
colorsCb.addActionListener(e -> {
grayLevelsLbl.setEnabled(!colorsCb.isSelected());
grayLevelsSlider.setEnabled(!colorsCb.isSelected());
});

final boolean ok = DialogFactory.showOkCancel(captureFrame, translate("capture"), pane, true, null);

if (ok) {
final CaptureEngineConfiguration newCaptureEngineConfiguration = new CaptureEngineConfiguration(tickMillisSlider.getValue(),
toGrayLevel(grayLevelsSlider.getValue()));
if (!newCaptureEngineConfiguration.equals(captureEngineConfiguration)) {
captureEngineConfiguration = newCaptureEngineConfiguration;
captureEngineConfiguration.persist();
sendCaptureConfiguration(captureEngineConfiguration);
}
toGrayLevel(grayLevelsSlider.getValue()), colorsCb.isSelected());
updateCaptureConfiguration(newCaptureEngineConfiguration);
}
}
};
Expand All @@ -434,6 +437,14 @@ public void actionPerformed(ActionEvent ev) {
return configure;
}

private void updateCaptureConfiguration(CaptureEngineConfiguration newCaptureEngineConfiguration) {
if (!newCaptureEngineConfiguration.equals(captureEngineConfiguration)) {
captureEngineConfiguration = newCaptureEngineConfiguration;
captureEngineConfiguration.persist();
sendCaptureConfiguration(captureEngineConfiguration);
}
}

private Gray8Bits toGrayLevel(int value) {
switch (value) {
case 6:
Expand Down Expand Up @@ -742,12 +753,29 @@ protected void done() {
}
}

public boolean isUpnpEnabled() {
synchronized (upnpEnabledLOCK) {
while (upnpEnabled == null) {
try {
upnpEnabledLOCK.wait();
} catch (InterruptedException e) {
Log.warn("Swallowed", e);
Thread.currentThread().interrupt();
}
}
return upnpEnabled;
}
}

private void initUpnp() {
CompletableFuture.supplyAsync(UPnP::isUPnPAvailable).thenApply(enabled -> {
Log.info(format("UPnP is %s", enabled.booleanValue() ? "enabled" : "disabled"));
upnpEnabled = enabled;
return enabled;
});
synchronized (upnpEnabledLOCK) {
CompletableFuture.supplyAsync(UPnP::isUPnPAvailable).thenApply(enabled -> {
Log.info(format("UPnP is %s", enabled.booleanValue() ? "enabled" : "disabled"));
upnpEnabled = enabled;
return enabled;
});
upnpEnabledLOCK.notifyAll();
}
}

private class MyDeCompressorEngineListener implements DeCompressorEngineListener {
Expand Down Expand Up @@ -788,7 +816,7 @@ private BufferedImage scaleImage(BufferedImage image, int width, int height) {
AffineTransform scaleTransform = AffineTransform.getScaleInstance(frame.getxFactor(), frame.getyFactor());
try {
AffineTransformOp bilinearScaleOp = new AffineTransformOp(scaleTransform, AffineTransformOp.TYPE_BILINEAR);
return bilinearScaleOp.filter(image, new BufferedImage(abs(width), abs(height), image.getType()));
return bilinearScaleOp.filter(image, new BufferedImage(abs(width), abs(height), image.getType() == 0 ? TYPE_INT_ARGB_PRE : TYPE_BYTE_GRAY));
} catch (ImagingOpException e) {
Log.error(e.getMessage());
return image;
Expand Down Expand Up @@ -828,11 +856,20 @@ public boolean onAccepted(Socket connection) {
* Should not block as called from the network receiving thread (!)
*/
@Override
public void onConnected(Socket connection, char osId, String inputLocale) {
public void onConnected(Socket connection, char osId, String inputLocale, int peerMajorVersion) {
assureCompatibility(peerMajorVersion);
sendCaptureConfiguration(captureEngineConfiguration);
sendCompressorConfiguration(compressorEngineConfiguration);
frame.resetCanvas();
frame.onSessionStarted(osId, inputLocale);
frame.onSessionStarted(osId, inputLocale, peerMajorVersion);
}

private void assureCompatibility(int peerMajorVersion) {
if (!Version.isColoredVersion(peerMajorVersion) && (captureEngineConfiguration.isCaptureColors() || captureEngineConfiguration.getCaptureQuantization().getLevels() < Gray8Bits.X_32.getLevels())) {
Log.warn(format("Pre color v%d.x.x peer detected: CaptureEngineConfiguration adjusted to %s", peerMajorVersion, Gray8Bits.X_128));
captureEngineConfiguration = new CaptureEngineConfiguration(captureEngineConfiguration.getCaptureTick(), Gray8Bits.X_128, false);
captureEngineConfiguration.persist();
}
}

@Override
Expand Down Expand Up @@ -881,17 +918,20 @@ public void onResizeScreen(int width, int height) {
@Override
public void onDisconnecting() {
frame.onDisconnecting();
networkConfiguration.setMonochromePeer(false);
}

@Override
public void onTerminating() {
Log.info("Session got terminated by peer");
frame.onTerminating();
networkConfiguration.setMonochromePeer(false);
}

@Override
public void onIOError(IOException error) {
frame.onIOError(error);
networkConfiguration.setMonochromePeer(false);
}

}
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/mpo/dayon/assistant/gui/AssistantFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import mpo.dayon.common.log.Log;
import mpo.dayon.common.monitoring.counter.Counter;
import mpo.dayon.common.utils.Language;
import mpo.dayon.common.version.Version;

import javax.swing.*;
import java.awt.*;
Expand Down Expand Up @@ -481,7 +482,7 @@ void onClipboardReceived() {
toggleTransferControls(true);
}

void onSessionStarted(char osId, String inputLocale) {
void onSessionStarted(char osId, String inputLocale, int assistedMajorVersion) {
this.osId = osId;
if (osId == 'm') {
windowsKeyToggleButton.setIcon(getOrCreateIcon(ImageNames.CMD));
Expand All @@ -490,6 +491,10 @@ void onSessionStarted(char osId, String inputLocale) {
windowsKeyToggleButton.setIcon(getOrCreateIcon(ImageNames.WIN));
windowsKeyToggleButton.setToolTipText(translate("send.winKey"));
}
if (Version.isOutdatedVersion(Version.get().getMajor(), assistedMajorVersion)) {
String infoMessage = format("%s%n%s", translate("outdated.msg1"), translate("outdated.msg2"));
JOptionPane.showMessageDialog(this, infoMessage, "", JOptionPane.INFORMATION_MESSAGE);
}
if (!inputLocale.isEmpty() && !inputLocale.equals(InputContext.getInstance().getLocale().toString())) {
String infoMessage = format("%s%n%s%n%s", translate("keyboardlayout.msg1", inputLocale), translate("keyboardlayout.msg2"), translate("keyboardlayout.msg3"));
JOptionPane.showMessageDialog(this, infoMessage, "", JOptionPane.INFORMATION_MESSAGE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import static java.lang.String.format;
import static mpo.dayon.common.utils.SystemUtilities.safeClose;
import static mpo.dayon.common.version.Version.isColoredVersion;
import static mpo.dayon.common.version.Version.isCompatibleVersion;

public class NetworkAssistantEngine extends NetworkEngine implements ReConfigurable<NetworkAssistantEngineConfiguration> {
Expand Down Expand Up @@ -289,6 +290,7 @@ private NetworkHelloMessage introduce(ObjectInputStream in) throws IOException {
Log.error(format("Incompatible assisted version: %d.%d", hello.getMajor(), hello.getMinor()));
throw new IOException("version.wrong");
}
configuration.setMonochromePeer(!isColoredVersion(hello.getMajor()));
return hello;
}

Expand All @@ -297,7 +299,7 @@ private NetworkHelloMessage introduce(ObjectInputStream in) throws IOException {
*/
public void sendCaptureConfiguration(CaptureEngineConfiguration configuration) {
if (sender != null) {
sender.sendCaptureConfiguration(configuration);
sender.sendCaptureConfiguration(configuration, this.configuration.isMonochromePeer());
}
}

Expand Down Expand Up @@ -359,7 +361,7 @@ private boolean fireOnAccepted(Socket connection) {
}

private void fireOnConnected(Socket connection, NetworkHelloMessage hello) {
listeners.getListeners().forEach(listener -> listener.onConnected(connection, hello.getOsId(), hello.getInputLocale()));
listeners.getListeners().forEach(listener -> listener.onConnected(connection, hello.getOsId(), hello.getInputLocale(), hello.getMajor()));
}

private void fireOnByteReceived(int count) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class NetworkAssistantEngineConfiguration extends Configuration {

private final String tokenServerUrl;

private boolean monochromePeer = false;

/**
* Default : takes its values from the current preferences.
*/
Expand All @@ -39,6 +41,14 @@ public String getTokenServerUrl() {
return tokenServerUrl;
}

public boolean isMonochromePeer() {
return monochromePeer;
}

public void setMonochromePeer(boolean monochromePeer) {
this.monochromePeer = monochromePeer;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public interface NetworkAssistantEngineListener extends Listener {
/**
* Should not block as called from the network receiving thread (!)
*/
void onConnected(Socket connection, char osId, String inputLocale);
void onConnected(Socket connection, char osId, String inputLocale, int peerMajorVersion);

/**
* Should not block as called from the network receiving thread (!)
Expand Down
Loading