Init
This commit is contained in:
commit
ba92bee6e6
21 changed files with 1945 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Project exclude paths
|
||||
/target/
|
39
JavaUSBTool.iml
Normal file
39
JavaUSBTool.iml
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-controls:linux:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-graphics:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-media:linux:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-fxml:linux:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-controls:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-graphics:linux:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-base:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-base:linux:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-controls:win:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-media:win:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-fxml:win:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-graphics:win:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-controls:mac:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-media:mac:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-fxml:mac:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-graphics:mac:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.usb4java:usb4java:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.usb4java:libusb4java:linux-x86:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.usb4java:libusb4java:linux-x86-64:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.usb4java:libusb4java:win32-x86:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.usb4java:libusb4java:win32-x86-64:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.usb4java:libusb4java:darwin-x86-64:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.usb4java:libusb4java:linux-arm:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.usb4java:libusb4java:linux-aarch64:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" />
|
||||
</component>
|
||||
</module>
|
196
pom.xml
Normal file
196
pom.xml
Normal file
|
@ -0,0 +1,196 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>loper</groupId>
|
||||
<name>JavaUSBTool</name>
|
||||
|
||||
<artifactId>javausbtool</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
|
||||
<url>https://github.com/developersu/javausbtool/</url>
|
||||
<description>
|
||||
Java USB Tool for prototyping and/or debug
|
||||
</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
<organization>
|
||||
<name>Dmitry Isaenko</name>
|
||||
<url>https://developersu.blogspot.com/</url>
|
||||
</organization>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>GNU General Public License v3</name>
|
||||
<url>http://www.gnu.org/licenses/gpl.txt</url>
|
||||
<distribution>manual</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>developer.su</id>
|
||||
<name>Dmitry Isaenko</name>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>+3</timezone>
|
||||
<url>https://developersu.blogspot.com/</url>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<issueManagement>
|
||||
<system>GitHub</system>
|
||||
<url>https://github.com/developer_su/${project.artifactId}/issues</url>
|
||||
</issueManagement>
|
||||
<!-- openJFX Linux -->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>linux</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-media</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>linux</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>linux</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>linux</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- openJFX Windows -->
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>win</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-media</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>win</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>win</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>win</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- openJFX MAC -->
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>mac</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-media</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>mac</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>mac</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>11</version>
|
||||
<classifier>mac</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.usb4java/usb4java -->
|
||||
<dependency>
|
||||
<groupId>org.usb4java</groupId>
|
||||
<artifactId>usb4java</artifactId>
|
||||
<version>1.3.0</version> <!-- Must be 1.2.0 for macOS lower than Mojave -->
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Don't generate default JAR without dependencies -->
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-jar</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Generate JAR with dependencies -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>javausbtool.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id> <!-- this is used for inheritance merges -->
|
||||
<phase>package</phase> <!-- bind to the packaging phase -->
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
66
src/main/java/javausbtool/AppPreferences.java
Normal file
66
src/main/java/javausbtool/AppPreferences.java
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool;
|
||||
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class AppPreferences {
|
||||
private static final AppPreferences INSTANCE = new AppPreferences();
|
||||
public static AppPreferences getInstance() { return INSTANCE; }
|
||||
|
||||
private Preferences preferences;
|
||||
|
||||
private AppPreferences(){
|
||||
preferences = Preferences.userRoot().node("javausbtool");
|
||||
}
|
||||
|
||||
public void setSaveTo(String path){preferences.put("save_to_path", path);}
|
||||
public String getSaveTo(){return preferences.get("save_to_path", System.getProperty("user.dir"));}
|
||||
|
||||
public String getRecentPath(){return preferences.get("recent_path", System.getProperty("user.home"));}
|
||||
public void setRecentPath(String path){preferences.put("recent_path", path);}
|
||||
|
||||
public double getSceneWidth(){ return preferences.getDouble("window_width", 850.0); }
|
||||
public void setSceneWidth(double value){ preferences.putDouble("window_width", value); }
|
||||
|
||||
public double getSceneHeight(){ return preferences.getDouble("window_height", 525.0); }
|
||||
public void setSceneHeight(double value){ preferences.putDouble("window_height", value); }
|
||||
|
||||
// Usb setup
|
||||
public short getVid(){ return (short) preferences.getInt("vid", 0x057E); }
|
||||
public void setVid(short value){ preferences.putInt("vid", value); }
|
||||
|
||||
public short getPid(){ return (short) preferences.getInt("pid", 0x3000); }
|
||||
public void setPid(short value){ preferences.putInt("pid", value); }
|
||||
|
||||
public int getInterface(){ return preferences.getInt("interface", 1); }
|
||||
public void setInterface(int value){ preferences.putInt("interface", value); }
|
||||
|
||||
public int getDeviceConfiguration(){ return preferences.getInt("devconfiguration", 0); }
|
||||
public void setDeviceConfiguration(int value){ preferences.putInt("devconfiguration", value); }
|
||||
|
||||
public boolean getHandleKernelDrvAutoDetach(){ return preferences.getBoolean("handle_kernel_driver", true); }
|
||||
public void setHandleKernelDrvAutoDetach(boolean value){preferences.putBoolean("handle_kernel_driver", value);}
|
||||
|
||||
public boolean getSoftResetOnHandle(){ return preferences.getBoolean("soft_reset_on_handle", false); }
|
||||
public void setSoftResetOnHandle(boolean value){preferences.putBoolean("soft_reset_on_handle", value);}
|
||||
|
||||
public int getReadBufferSize(){ return preferences.getInt("read_buffer_size", 512); }
|
||||
public void setReadBufferSize(int value){ preferences.putInt("read_buffer_size", value); }
|
||||
}
|
76
src/main/java/javausbtool/JFXMain.java
Normal file
76
src/main/java/javausbtool/JFXMain.java
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Stage;
|
||||
import javausbtool.controllers.LandingPageController;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class JFXMain extends Application {
|
||||
|
||||
public static final String appVersion = "v0.1";
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception{
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/landingPage.fxml"));
|
||||
|
||||
Parent root = loader.load();
|
||||
|
||||
primaryStage.getIcons().addAll(
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon32x32.png")),
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon48x48.png")),
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon64x64.png")),
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon128x128.png"))
|
||||
);
|
||||
|
||||
primaryStage.setTitle("JavaUSBTool "+appVersion);
|
||||
primaryStage.setMinWidth(650);
|
||||
primaryStage.setMinHeight(450);
|
||||
Scene mainScene = new Scene(root,
|
||||
AppPreferences.getInstance().getSceneWidth(),
|
||||
AppPreferences.getInstance().getSceneHeight()
|
||||
);
|
||||
|
||||
mainScene.getStylesheets().add("/res/app_light.css");
|
||||
|
||||
primaryStage.setScene(mainScene);
|
||||
primaryStage.show();
|
||||
|
||||
LandingPageController controller = loader.getController();
|
||||
primaryStage.setOnHidden(e-> {
|
||||
AppPreferences.getInstance().setSceneHeight(mainScene.getHeight());
|
||||
AppPreferences.getInstance().setSceneWidth(mainScene.getWidth());
|
||||
controller.exit();
|
||||
});
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
if ((args.length == 1) && (args[0].equals("-v") || args[0].equals("--version")))
|
||||
System.out.println("JavaUSBTool "+JFXMain.appVersion);
|
||||
else
|
||||
launch(args);
|
||||
}
|
||||
}
|
26
src/main/java/javausbtool/Main.java
Normal file
26
src/main/java/javausbtool/Main.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool;
|
||||
|
||||
/**
|
||||
* It's a workaround to execute JavaFX application.
|
||||
* */
|
||||
public class Main {
|
||||
public static void main(String[] args){ JFXMain.main(args); }
|
||||
}
|
37
src/main/java/javausbtool/MediatorControl.java
Normal file
37
src/main/java/javausbtool/MediatorControl.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool;
|
||||
|
||||
import javausbtool.controllers.LandingPageController;
|
||||
|
||||
public class MediatorControl {
|
||||
private LandingPageController applicationController;
|
||||
|
||||
public static MediatorControl getInstance(){
|
||||
return MediatorControlHold.INSTANCE;
|
||||
}
|
||||
|
||||
private static class MediatorControlHold {
|
||||
private static final MediatorControl INSTANCE = new MediatorControl();
|
||||
}
|
||||
public void setController(LandingPageController controller){
|
||||
this.applicationController = controller;
|
||||
}
|
||||
public LandingPageController getContoller(){ return this.applicationController; }
|
||||
}
|
219
src/main/java/javausbtool/controllers/LandingPageController.java
Normal file
219
src/main/java/javausbtool/controllers/LandingPageController.java
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool.controllers;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import javausbtool.AppPreferences;
|
||||
import javausbtool.MediatorControl;
|
||||
import javausbtool.usb.UsbCommunications;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class LandingPageController implements Initializable {
|
||||
@FXML
|
||||
public TextArea logArea;
|
||||
@FXML
|
||||
public ProgressBar progressBar;
|
||||
|
||||
@FXML
|
||||
private TextField vidTf,
|
||||
pidTf,
|
||||
devInterfaceTf,
|
||||
devConfigurationTf,
|
||||
readBufferSizeTf;
|
||||
|
||||
@FXML
|
||||
private Label saveToLbl, sendFileLbl;
|
||||
|
||||
@FXML
|
||||
private CheckBox handleKernelDrvDetachCb,
|
||||
mandatorySoftResetCb;
|
||||
|
||||
|
||||
@FXML
|
||||
private Button changeSaveToBtn, fileToSendBtn, startBtn, stopBtn;
|
||||
|
||||
@FXML
|
||||
private RadioButton readOnStartRb,
|
||||
writeOnStartRb;
|
||||
|
||||
private String previouslyOpenedPath;
|
||||
private File writeOnStartFile;
|
||||
private Task<Void> usbCommunications;
|
||||
private Thread workThread;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
MediatorControl.getInstance().setController(this);
|
||||
|
||||
AppPreferences pref = AppPreferences.getInstance();
|
||||
vidTf.setText(Short.toString(pref.getVid()));
|
||||
pidTf.setText(Short.toString(pref.getPid()));
|
||||
devInterfaceTf.setText(Integer.toString(pref.getInterface()));
|
||||
devConfigurationTf.setText(Integer.toString(pref.getDeviceConfiguration()));
|
||||
handleKernelDrvDetachCb.setSelected(pref.getHandleKernelDrvAutoDetach());
|
||||
mandatorySoftResetCb.setSelected(pref.getSoftResetOnHandle());
|
||||
|
||||
readBufferSizeTf.setText(Integer.toString(pref.getReadBufferSize()));
|
||||
|
||||
vidTf.setTextFormatter(getNumericTextFormatter());
|
||||
pidTf.setTextFormatter(getNumericTextFormatter());
|
||||
devConfigurationTf.setTextFormatter(getNumericTextFormatter());
|
||||
devConfigurationTf.setTextFormatter(getNumericTextFormatter());
|
||||
|
||||
readBufferSizeTf.setTextFormatter(getNumericTextFormatter());
|
||||
|
||||
saveToLbl.setText(pref.getSaveTo());
|
||||
changeSaveToBtn.setOnAction(event -> setSaveToFolder());
|
||||
|
||||
ToggleGroup readWriteToggleGrp = new ToggleGroup();
|
||||
readWriteToggleGrp.getToggles().addAll(readOnStartRb, writeOnStartRb);
|
||||
readOnStartRb.setSelected(true);
|
||||
|
||||
previouslyOpenedPath = System.getProperty("user.home");
|
||||
|
||||
fileToSendBtn.setOnAction(event -> selectFileToSendInitially());
|
||||
|
||||
startBtn.setOnAction(event -> startProcess());
|
||||
stopBtn.setOnAction(event -> stopProcess());
|
||||
}
|
||||
|
||||
private TextFormatter getNumericTextFormatter(){
|
||||
return new TextFormatter<>(change -> {
|
||||
if (change.getControlNewText().matches("^[0-9]{0,}$"))
|
||||
return change;
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void setSaveToFolder() {
|
||||
DirectoryChooser dirChooser = new DirectoryChooser();
|
||||
dirChooser.setTitle("Save files to...");
|
||||
dirChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||
File dir = dirChooser.showDialog(progressBar.getScene().getWindow());
|
||||
if (dir != null && dir.exists())
|
||||
saveToLbl.setText(dir.getAbsolutePath());
|
||||
}
|
||||
|
||||
private void selectFileToSendInitially(){
|
||||
File file;
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("Select file");
|
||||
|
||||
File validator = new File(previouslyOpenedPath);
|
||||
if (validator.exists() && validator.isDirectory())
|
||||
fileChooser.setInitialDirectory(validator);
|
||||
else
|
||||
return;
|
||||
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Any", "*.*"));
|
||||
|
||||
file = fileChooser.showOpenDialog(sendFileLbl.getScene().getWindow());
|
||||
if (file != null) {
|
||||
sendFileLbl.setText(file.getName());
|
||||
previouslyOpenedPath = file.getParent();
|
||||
writeOnStartFile = file;
|
||||
}
|
||||
}
|
||||
|
||||
private void startProcess(){
|
||||
logArea.clear();
|
||||
if (writeOnStartRb.isSelected() && writeOnStartFile == null){
|
||||
logArea.appendText("'Write on start' option selected but no file defined\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((workThread != null && workThread.isAlive())){
|
||||
logArea.appendText("Something still running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
usbCommunications = new UsbCommunications(
|
||||
(short) Integer.parseInt(vidTf.getText()),
|
||||
(short) Integer.parseInt(pidTf.getText()),
|
||||
Integer.parseInt(devInterfaceTf.getText()),
|
||||
Integer.parseInt(devConfigurationTf.getText()),
|
||||
handleKernelDrvDetachCb.isSelected(),
|
||||
mandatorySoftResetCb.isSelected(),
|
||||
Integer.parseInt(readBufferSizeTf.getText()),
|
||||
saveToLbl.getText(),
|
||||
readOnStartRb.isSelected(),
|
||||
writeOnStartFile
|
||||
);
|
||||
workThread = new Thread(usbCommunications);
|
||||
workThread.setDaemon(true);
|
||||
workThread.start();
|
||||
}
|
||||
private void stopProcess(){
|
||||
if (workThread != null && workThread.isAlive()){
|
||||
usbCommunications.cancel(false);
|
||||
logArea.appendText("Stop request sent\n");
|
||||
}
|
||||
else
|
||||
logArea.appendText("Nothing to stop\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Save any changes made on settings on app
|
||||
* */
|
||||
public void exit() {
|
||||
AppPreferences pref = AppPreferences.getInstance();
|
||||
short shortValue;
|
||||
try{
|
||||
if ((shortValue = Short.parseShort(vidTf.getText())) > 0)
|
||||
pref.setVid(shortValue);
|
||||
}
|
||||
catch (NumberFormatException e){ e.printStackTrace(); }
|
||||
try{
|
||||
if ((shortValue = Short.parseShort(pidTf.getText())) > 0)
|
||||
pref.setPid(shortValue);
|
||||
}
|
||||
catch (NumberFormatException e){ e.printStackTrace(); }
|
||||
|
||||
int intValue;
|
||||
try {
|
||||
if ((intValue = Integer.parseInt(devInterfaceTf.getText())) > 0)
|
||||
pref.setInterface(intValue);
|
||||
}
|
||||
catch (NumberFormatException e){ e.printStackTrace(); }
|
||||
try {
|
||||
if ((intValue = Integer.parseInt(devConfigurationTf.getText())) > 0)
|
||||
pref.setDeviceConfiguration(intValue);
|
||||
}
|
||||
catch (NumberFormatException e){ e.printStackTrace(); }
|
||||
|
||||
pref.setHandleKernelDrvAutoDetach(handleKernelDrvDetachCb.isSelected());
|
||||
pref.setSoftResetOnHandle(mandatorySoftResetCb.isSelected());
|
||||
|
||||
pref.setSaveTo(saveToLbl.getText());
|
||||
|
||||
try {
|
||||
if ((intValue = Integer.parseInt(readBufferSizeTf.getText())) > 0)
|
||||
pref.setReadBufferSize(intValue);
|
||||
}
|
||||
catch (NumberFormatException e){ e.printStackTrace(); }
|
||||
}
|
||||
}
|
63
src/main/java/javausbtool/misc/LogPrinter.java
Normal file
63
src/main/java/javausbtool/misc/LogPrinter.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool.misc;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
public class LogPrinter {
|
||||
private MessagesConsumer msgConsumer;
|
||||
private BlockingQueue<String> msgQueue;
|
||||
private BlockingQueue<Double> progressQueue;
|
||||
|
||||
public LogPrinter(){
|
||||
this.msgQueue = new LinkedBlockingQueue<>();
|
||||
this.progressQueue = new LinkedBlockingQueue<>();
|
||||
this.msgConsumer = new MessagesConsumer(this.msgQueue, this.progressQueue);
|
||||
this.msgConsumer.start();
|
||||
}
|
||||
/**
|
||||
* This is what will print to textArea of the application.
|
||||
* */
|
||||
public void print(String message){
|
||||
try {
|
||||
msgQueue.put(message+"\n");
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Update progress for progress bar
|
||||
* */
|
||||
public void updateProgress(Double value) {
|
||||
try {
|
||||
progressQueue.put(value);
|
||||
}
|
||||
catch (InterruptedException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* When we're done - close it
|
||||
* */
|
||||
public void close(){
|
||||
msgConsumer.interrupt();
|
||||
}
|
||||
}
|
80
src/main/java/javausbtool/misc/MessagesConsumer.java
Normal file
80
src/main/java/javausbtool/misc/MessagesConsumer.java
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool.misc;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javausbtool.MediatorControl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
public class MessagesConsumer extends AnimationTimer {
|
||||
private final BlockingQueue<String> msgQueue;
|
||||
private final TextArea logsArea;
|
||||
|
||||
private final BlockingQueue<Double> progressQueue;
|
||||
private final ProgressBar progressBar;
|
||||
|
||||
private boolean isInterrupted;
|
||||
|
||||
MessagesConsumer(BlockingQueue<String> msgQueue, BlockingQueue<Double> progressQueue){
|
||||
this.isInterrupted = false;
|
||||
|
||||
this.msgQueue = msgQueue;
|
||||
this.logsArea = MediatorControl.getInstance().getContoller().logArea;
|
||||
|
||||
this.progressQueue = progressQueue;
|
||||
this.progressBar = MediatorControl.getInstance().getContoller().progressBar;
|
||||
|
||||
progressBar.setProgress(0.0);
|
||||
|
||||
progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(long l) {
|
||||
ArrayList<String> messages = new ArrayList<>();
|
||||
int msgRecieved = msgQueue.drainTo(messages);
|
||||
if (msgRecieved > 0)
|
||||
messages.forEach(logsArea::appendText);
|
||||
|
||||
ArrayList<Double> progress = new ArrayList<>();
|
||||
int progressRecieved = progressQueue.drainTo(progress);
|
||||
if (progressRecieved > 0) {
|
||||
progress.forEach(prg -> {
|
||||
if (prg != 1.0)
|
||||
progressBar.setProgress(prg);
|
||||
else
|
||||
progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
|
||||
});
|
||||
}
|
||||
|
||||
if (isInterrupted) {
|
||||
progressBar.setProgress(0.0);
|
||||
this.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void interrupt(){
|
||||
this.isInterrupted = true;
|
||||
}
|
||||
}
|
105
src/main/java/javausbtool/usb/UsbCommunications.java
Normal file
105
src/main/java/javausbtool/usb/UsbCommunications.java
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool.usb;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
import javausbtool.misc.LogPrinter;
|
||||
import org.usb4java.DeviceHandle;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class UsbCommunications extends Task<Void> {
|
||||
|
||||
private LogPrinter logPrinter;
|
||||
|
||||
private short vid;
|
||||
private short pid;
|
||||
private int interfaceNumber;
|
||||
private int configurationNumber;
|
||||
private boolean handleAutoKernelDriverDetach;
|
||||
private boolean mandatoryDeviceReset;
|
||||
private boolean shouldRead;
|
||||
private File writeOnStartFile;
|
||||
|
||||
private int readBufferCapacity;
|
||||
private String saveRepliesTo;
|
||||
|
||||
public UsbCommunications(
|
||||
short vid,
|
||||
short pid,
|
||||
int interfaceNumber,
|
||||
int configurationNumber,
|
||||
boolean handleAutoKernelDriverDetach,
|
||||
boolean mandatoryDeviceReset,
|
||||
|
||||
int readBufferCapacity,
|
||||
String saveRepliesTo,
|
||||
boolean shouldRead,
|
||||
File writeOnStartFile
|
||||
)
|
||||
{
|
||||
this.logPrinter = new LogPrinter();
|
||||
this.vid = vid;
|
||||
this.pid = pid;
|
||||
this.interfaceNumber = interfaceNumber;
|
||||
this.configurationNumber = configurationNumber;
|
||||
this.handleAutoKernelDriverDetach = handleAutoKernelDriverDetach;
|
||||
this.mandatoryDeviceReset = mandatoryDeviceReset;
|
||||
this.readBufferCapacity = readBufferCapacity;
|
||||
this.saveRepliesTo = saveRepliesTo;
|
||||
this.shouldRead = shouldRead;
|
||||
this.writeOnStartFile = writeOnStartFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void call() {
|
||||
logPrinter.print("\tStart UsbCommunications()");
|
||||
|
||||
UsbConnect usbConnect = UsbConnect.connect(logPrinter,
|
||||
vid,
|
||||
pid,
|
||||
interfaceNumber,
|
||||
configurationNumber,
|
||||
handleAutoKernelDriverDetach,
|
||||
mandatoryDeviceReset);
|
||||
|
||||
if (! usbConnect.isConnected()){
|
||||
logPrinter.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
DeviceHandle handler = usbConnect.getNsHandler();
|
||||
|
||||
new UsbLoop(handler,
|
||||
readBufferCapacity,
|
||||
writeOnStartFile,
|
||||
this,
|
||||
logPrinter,
|
||||
saveRepliesTo,
|
||||
shouldRead
|
||||
);
|
||||
|
||||
usbConnect.close();
|
||||
|
||||
logPrinter.close();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
219
src/main/java/javausbtool/usb/UsbConnect.java
Normal file
219
src/main/java/javausbtool/usb/UsbConnect.java
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool.usb;
|
||||
|
||||
import javausbtool.misc.LogPrinter;
|
||||
import org.usb4java.*;
|
||||
|
||||
public class UsbConnect {
|
||||
private Context contextNS;
|
||||
private DeviceHandle handlerNS;
|
||||
private Device deviceNS;
|
||||
|
||||
private LogPrinter logPrinter;
|
||||
|
||||
private boolean connected;
|
||||
|
||||
private short VENDOR_ID;
|
||||
private short PRODUCT_ID;
|
||||
private int INTERFACE_NUMBER;
|
||||
|
||||
private int returningValue;
|
||||
private DeviceList deviceList;
|
||||
|
||||
public static UsbConnect connect(LogPrinter logPrinter,
|
||||
short vid,
|
||||
short pid,
|
||||
int interfaceNumber,
|
||||
int configurationNumber,
|
||||
boolean handleAutoKernelDriverDetach,
|
||||
boolean mandatoryDeviceReset){
|
||||
UsbConnect usbConnect = new UsbConnect(logPrinter);
|
||||
usbConnect.VENDOR_ID = vid;
|
||||
usbConnect.PRODUCT_ID = pid;
|
||||
usbConnect.INTERFACE_NUMBER = interfaceNumber;
|
||||
try {
|
||||
usbConnect.createContextAndInitLibUSB();
|
||||
usbConnect.getDeviceList();
|
||||
usbConnect.findDevice();
|
||||
usbConnect.openDevice();
|
||||
usbConnect.freeDeviceList();
|
||||
if (handleAutoKernelDriverDetach)
|
||||
usbConnect.setAutoDetachKernelDriver();
|
||||
if (mandatoryDeviceReset)
|
||||
usbConnect.resetDevice();
|
||||
usbConnect.setConfiguration(configurationNumber);
|
||||
usbConnect.claimInterface();
|
||||
usbConnect.connected = true;
|
||||
}
|
||||
catch (Exception e){
|
||||
logPrinter.print(e.getMessage());
|
||||
usbConnect.close();
|
||||
}
|
||||
return usbConnect;
|
||||
}
|
||||
|
||||
private UsbConnect(){}
|
||||
|
||||
private UsbConnect(LogPrinter logPrinter){
|
||||
this.logPrinter = logPrinter;
|
||||
this.connected = false;
|
||||
};
|
||||
|
||||
private void createContextAndInitLibUSB() throws Exception{
|
||||
// Creating Context required by libusb. Optional? Consider removing.
|
||||
contextNS = new Context();
|
||||
|
||||
returningValue = LibUsb.init(contextNS);
|
||||
if (returningValue != LibUsb.SUCCESS)
|
||||
throw new Exception("LibUSB initialization failed: "+UsbErrorCodes.getErrCode(returningValue));
|
||||
}
|
||||
|
||||
private void getDeviceList() throws Exception{
|
||||
deviceList = new DeviceList();
|
||||
returningValue = LibUsb.getDeviceList(contextNS, deviceList);
|
||||
if (returningValue < 0)
|
||||
throw new Exception("Can't get device list: "+UsbErrorCodes.getErrCode(returningValue));
|
||||
}
|
||||
|
||||
private void findDevice() throws Exception{
|
||||
// Searching for NS in devices: looking for NS
|
||||
DeviceDescriptor descriptor;
|
||||
|
||||
for (Device device: deviceList){
|
||||
descriptor = getDeviceDescriptor(device);
|
||||
|
||||
if ((descriptor.idVendor() == VENDOR_ID) && descriptor.idProduct() == PRODUCT_ID){
|
||||
deviceNS = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (deviceNS == null) {
|
||||
this.freeDeviceList();
|
||||
throw new Exception("NS not found in connected USB devices");
|
||||
}
|
||||
}
|
||||
|
||||
private DeviceDescriptor getDeviceDescriptor(Device device) throws Exception{
|
||||
DeviceDescriptor descriptor = new DeviceDescriptor();
|
||||
|
||||
returningValue = LibUsb.getDeviceDescriptor(device, descriptor);
|
||||
|
||||
if (returningValue != LibUsb.SUCCESS){
|
||||
this.freeDeviceList();
|
||||
throw new Exception("Get USB device descriptor failure: "+UsbErrorCodes.getErrCode(returningValue));
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
private void openDevice() throws Exception{
|
||||
// Handle NS device
|
||||
handlerNS = new DeviceHandle();
|
||||
returningValue = LibUsb.open(deviceNS, handlerNS);
|
||||
|
||||
if (returningValue == LibUsb.SUCCESS)
|
||||
return;
|
||||
|
||||
handlerNS = null; // Avoid issue on close();
|
||||
if (returningValue == LibUsb.ERROR_ACCESS) {
|
||||
throw new Exception(String.format(
|
||||
"Can't open NS USB device: %s\n" +
|
||||
"Double check that you have administrator privileges (you're 'root') or check 'udev' rules set for this user (linux only)!\n\n" +
|
||||
"Steps to set 'udev' rules:\n" +
|
||||
"root # vim /etc/udev/rules.d/99-NS.rules\n" +
|
||||
"SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", GROUP=\"plugdev\"\n" +
|
||||
"root # udevadm control --reload-rules && udevadm trigger\n", UsbErrorCodes.getErrCode(returningValue), VENDOR_ID, PRODUCT_ID));
|
||||
}
|
||||
else
|
||||
throw new Exception("Can't open NS USB device: "+UsbErrorCodes.getErrCode(returningValue));
|
||||
}
|
||||
|
||||
private void freeDeviceList(){
|
||||
LibUsb.freeDeviceList(deviceList, true);
|
||||
}
|
||||
|
||||
private void setAutoDetachKernelDriver(){
|
||||
// Actually, there are no drivers in Linux kernel which uses this device.
|
||||
returningValue = LibUsb.setAutoDetachKernelDriver(handlerNS, true);
|
||||
if (returningValue != LibUsb.SUCCESS)
|
||||
logPrinter.print("Skip kernel driver attach & detach ("+UsbErrorCodes.getErrCode(returningValue)+")");
|
||||
}
|
||||
|
||||
private void resetDevice() throws Exception{
|
||||
returningValue = LibUsb.resetDevice(handlerNS);
|
||||
if (returningValue != LibUsb.SUCCESS)
|
||||
throw new Exception("Reset device\n Returned: "+UsbErrorCodes.getErrCode(returningValue));
|
||||
}
|
||||
|
||||
private void setConfiguration(int configuration) throws Exception{
|
||||
returningValue = LibUsb.setConfiguration(handlerNS, configuration);
|
||||
if (returningValue != LibUsb.SUCCESS)
|
||||
throw new Exception("Unable to set active configuration on device: "+UsbErrorCodes.getErrCode(returningValue));
|
||||
}
|
||||
private void claimInterface() throws Exception{
|
||||
// Claim interface
|
||||
returningValue = LibUsb.claimInterface(handlerNS, INTERFACE_NUMBER);
|
||||
if (returningValue != LibUsb.SUCCESS)
|
||||
throw new Exception("Claim interface failure: "+UsbErrorCodes.getErrCode(returningValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get USB status
|
||||
* @return status of connection
|
||||
*/
|
||||
public boolean isConnected() { return connected; }
|
||||
/**
|
||||
* Getter for handler
|
||||
* @return DeviceHandle of NS
|
||||
*/
|
||||
public DeviceHandle getNsHandler(){ return handlerNS; }
|
||||
/**
|
||||
* Getter for 'Bus ID' where NS located found
|
||||
*/
|
||||
public int getNsBus(){
|
||||
return LibUsb.getBusNumber(deviceNS);
|
||||
}
|
||||
/**
|
||||
* Getter for 'Device address' where NS located at
|
||||
*/
|
||||
public int getNsAddress(){
|
||||
return LibUsb.getDeviceAddress(deviceNS);
|
||||
}
|
||||
/**
|
||||
* Correct exit
|
||||
* */
|
||||
public void close(){
|
||||
// Close handler in the end
|
||||
if (handlerNS != null) {
|
||||
// Try to release interface
|
||||
returningValue = LibUsb.releaseInterface(handlerNS, INTERFACE_NUMBER);
|
||||
|
||||
if (returningValue != LibUsb.SUCCESS) {
|
||||
logPrinter.print("Release interface failure: " +
|
||||
UsbErrorCodes.getErrCode(returningValue) +
|
||||
" (sometimes it's not an issue)");
|
||||
}
|
||||
|
||||
LibUsb.close(handlerNS);
|
||||
}
|
||||
// Close context in the end
|
||||
if (contextNS != null)
|
||||
LibUsb.exit(contextNS);
|
||||
}
|
||||
}
|
56
src/main/java/javausbtool/usb/UsbErrorCodes.java
Normal file
56
src/main/java/javausbtool/usb/UsbErrorCodes.java
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool.usb;
|
||||
|
||||
import org.usb4java.LibUsb;
|
||||
|
||||
public class UsbErrorCodes {
|
||||
public static String getErrCode(int value){
|
||||
switch (value){
|
||||
case LibUsb.ERROR_ACCESS:
|
||||
return "ERROR_ACCESS";
|
||||
case LibUsb.ERROR_BUSY:
|
||||
return "ERROR_BUSY";
|
||||
case LibUsb.ERROR_INTERRUPTED:
|
||||
return "ERROR_INTERRUPTED";
|
||||
case LibUsb.ERROR_INVALID_PARAM:
|
||||
return "ERROR_INVALID_PARAM";
|
||||
case LibUsb.ERROR_IO:
|
||||
return "ERROR_IO";
|
||||
case LibUsb.ERROR_NO_DEVICE:
|
||||
return "ERROR_NO_DEVICE";
|
||||
case LibUsb.ERROR_NO_MEM:
|
||||
return "ERROR_NO_MEM";
|
||||
case LibUsb.ERROR_NOT_FOUND:
|
||||
return "ERROR_NOT_FOUND";
|
||||
case LibUsb.ERROR_NOT_SUPPORTED:
|
||||
return "ERROR_NOT_SUPPORTED";
|
||||
case LibUsb.ERROR_OTHER:
|
||||
return "ERROR_OTHER";
|
||||
case LibUsb.ERROR_OVERFLOW:
|
||||
return "ERROR_OVERFLOW";
|
||||
case LibUsb.ERROR_PIPE:
|
||||
return "ERROR_PIPE";
|
||||
case LibUsb.ERROR_TIMEOUT:
|
||||
return "ERROR_TIMEOUT";
|
||||
default:
|
||||
return Integer.toString(value);
|
||||
}
|
||||
}
|
||||
}
|
202
src/main/java/javausbtool/usb/UsbLoop.java
Normal file
202
src/main/java/javausbtool/usb/UsbLoop.java
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
Copyright 2020 Dmitry Isaenko
|
||||
|
||||
This file is part of JavaUSBTool.
|
||||
|
||||
JavaUSBTool 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JavaUSBTool 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 JavaUSBTool. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package javausbtool.usb;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
import javausbtool.misc.LogPrinter;
|
||||
import org.usb4java.DeviceHandle;
|
||||
import org.usb4java.LibUsb;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* Tinfoil processing
|
||||
* */
|
||||
class UsbLoop {
|
||||
|
||||
private LogPrinter logPrinter;
|
||||
private DeviceHandle handlerNS;
|
||||
private Task<Void> task;
|
||||
private int readBufferCapacity;
|
||||
private long readCounter;
|
||||
private File saveRepliesFolder;
|
||||
|
||||
public UsbLoop(DeviceHandle handler,
|
||||
int readBufferCapacity,
|
||||
File fileToSendOnStart,
|
||||
Task<Void> task,
|
||||
LogPrinter logPrinter,
|
||||
String saveRepliesTo,
|
||||
boolean shouldRead
|
||||
){
|
||||
this.handlerNS = handler;
|
||||
this.task = task;
|
||||
this.logPrinter = logPrinter;
|
||||
this.readBufferCapacity = readBufferCapacity;
|
||||
this.readCounter = 0;
|
||||
|
||||
logPrinter.print("============= UsbProtocol =============");
|
||||
|
||||
this.saveRepliesFolder = new File(saveRepliesTo+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||
saveRepliesFolder.mkdirs();
|
||||
|
||||
logPrinter.print("Save replies to dir: "+saveRepliesFolder.getName());
|
||||
|
||||
if (! shouldRead) {
|
||||
try {
|
||||
writeFile(fileToSendOnStart);
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
logPrinter.print(e.getMessage());
|
||||
logPrinter.print("Terminating now");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
readLoop();
|
||||
}
|
||||
|
||||
private void readLoop(){
|
||||
while (true){
|
||||
try {
|
||||
dumpData(readUsb());
|
||||
}
|
||||
catch (InterruptedException ioe){
|
||||
logPrinter.print("Execution interrupted");
|
||||
return;
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
logPrinter.print(e.getMessage());
|
||||
logPrinter.print("Terminating now");
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void writeFile(File file) throws IOException, NullPointerException, ArithmeticException {
|
||||
byte[] readBuffer;
|
||||
long currentOffset = 0;
|
||||
int chunk = 8388608;
|
||||
long size = file.length();
|
||||
|
||||
BufferedInputStream bufferedInStream = new BufferedInputStream(new FileInputStream(file));
|
||||
|
||||
while (currentOffset < size) {
|
||||
if ((currentOffset + chunk) >= size)
|
||||
chunk = Math.toIntExact(size - currentOffset);
|
||||
|
||||
logPrinter.updateProgress((currentOffset + chunk) / (size / 100.0) / 100.0);
|
||||
|
||||
readBuffer = new byte[chunk];
|
||||
|
||||
if (bufferedInStream.read(readBuffer) != chunk)
|
||||
throw new IOException("Reading from file stream suddenly ended.");
|
||||
|
||||
if (writeUsb(readBuffer))
|
||||
throw new IOException("Failure during file transfer.");
|
||||
currentOffset += chunk;
|
||||
}
|
||||
bufferedInStream.close();
|
||||
logPrinter.updateProgress(1.0);
|
||||
}
|
||||
|
||||
private void dumpData(byte[] data) throws Exception{
|
||||
this.readCounter++;
|
||||
File chunkFile = new File(saveRepliesFolder.getAbsolutePath()+File.separator+readCounter+".bin");
|
||||
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(chunkFile, false));
|
||||
bos.write(data);
|
||||
bos.close();
|
||||
}
|
||||
/**
|
||||
* Sending any byte array to USB device
|
||||
* @return 'false' if no issues
|
||||
* 'true' if errors happened
|
||||
* */
|
||||
private boolean writeUsb(byte[] message) {
|
||||
ByteBuffer writeBuffer = ByteBuffer.allocateDirect(message.length); //writeBuffer.order() equals BIG_ENDIAN;
|
||||
writeBuffer.put(message); // Don't do writeBuffer.rewind();
|
||||
IntBuffer writeBufTransferred = IntBuffer.allocate(1);
|
||||
int result;
|
||||
//int varVar = 0; //todo:remove
|
||||
while (! task.isCancelled()) {
|
||||
/*
|
||||
if (varVar != 0)
|
||||
logPrinter.print("writeUsb() retry cnt: "+varVar, EMsgType.INFO); //NOTE: DEBUG
|
||||
varVar++;
|
||||
*/
|
||||
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 5050); // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01
|
||||
|
||||
switch (result){
|
||||
case LibUsb.SUCCESS:
|
||||
if (writeBufTransferred.get() == message.length)
|
||||
return false;
|
||||
logPrinter.print("TF Data transfer issue [write]" +
|
||||
"\n Requested: "+message.length+
|
||||
"\n Transferred: "+writeBufTransferred.get());
|
||||
return true;
|
||||
case LibUsb.ERROR_TIMEOUT:
|
||||
//System.out.println("writeBuffer position: "+writeBuffer.position()+" "+writeBufTransferred.get());
|
||||
//writeBufTransferred.clear(); // MUST BE HERE IF WE 'GET()' IT
|
||||
continue;
|
||||
default:
|
||||
logPrinter.print("TF Data transfer issue [write]" +
|
||||
"\n Returned: "+ UsbErrorCodes.getErrCode(result) +
|
||||
"\n (execution stopped)");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
logPrinter.print("INFO TF Execution interrupted");
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Reading what USB device responded.
|
||||
* @return byte array if data read successful
|
||||
* 'null' if read failed
|
||||
* */
|
||||
private byte[] readUsb() throws Exception{
|
||||
ByteBuffer readBuffer = ByteBuffer.allocateDirect(readBufferCapacity);
|
||||
// We can limit it to 32 bytes, but there is a non-zero chance to got OVERFLOW from libusb.
|
||||
IntBuffer readBufTransferred = IntBuffer.allocate(1);
|
||||
int result;
|
||||
while (! task.isCancelled()) {
|
||||
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
|
||||
|
||||
switch (result) {
|
||||
case LibUsb.SUCCESS:
|
||||
int trans = readBufTransferred.get();
|
||||
byte[] receivedBytes = new byte[trans];
|
||||
readBuffer.get(receivedBytes);
|
||||
return receivedBytes;
|
||||
case LibUsb.ERROR_TIMEOUT:
|
||||
continue;
|
||||
default:
|
||||
throw new Exception("Data transfer issue [read]" +
|
||||
"\n Returned: " + UsbErrorCodes.getErrCode(result)+
|
||||
"\n (execution stopped)");
|
||||
}
|
||||
}
|
||||
throw new InterruptedException("Execution interrupted");
|
||||
}
|
||||
}
|
117
src/main/resources/landingPage.fxml
Normal file
117
src/main/resources/landingPage.fxml
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ProgressBar?>
|
||||
<?import javafx.scene.control.RadioButton?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.control.SplitPane?>
|
||||
<?import javafx.scene.control.TextArea?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.control.TitledPane?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
|
||||
<AnchorPane minHeight="400.0" minWidth="400.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javausbtool.controllers.LandingPageController">
|
||||
<children>
|
||||
<VBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<SplitPane dividerPositions="0.5" VBox.vgrow="ALWAYS">
|
||||
<items>
|
||||
<VBox spacing="5.0">
|
||||
<children>
|
||||
<TitledPane expanded="false" text="USB Connection configuration">
|
||||
<content>
|
||||
<VBox spacing="5.0">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label minWidth="100.0" text="VID" />
|
||||
<TextField fx:id="vidTf" />
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label minWidth="100.0" text="PID" />
|
||||
<TextField fx:id="pidTf" />
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label minWidth="100.0" text="Interface" />
|
||||
<TextField fx:id="devInterfaceTf" />
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label minWidth="100.0" text="Configuration" />
|
||||
<TextField fx:id="devConfigurationTf" />
|
||||
</children>
|
||||
</HBox>
|
||||
<CheckBox fx:id="handleKernelDrvDetachCb" mnemonicParsing="false" text="Automatically handle kernel driver detach" />
|
||||
<CheckBox fx:id="mandatorySoftResetCb" mnemonicParsing="false" text="Perform soft-reset device once handle" />
|
||||
</children>
|
||||
</VBox>
|
||||
</content>
|
||||
</TitledPane>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Button fx:id="changeSaveToBtn" mnemonicParsing="false">
|
||||
<graphic>
|
||||
<SVGPath content="M3,4C1.89,4 1,4.89 1,6V18A2,2 0 0,0 3,20H11V18.11L21,8.11V8C21,6.89 20.1,6 19,6H11L9,4H3M21.04,11.13C20.9,11.13 20.76,11.19 20.65,11.3L19.65,12.3L21.7,14.35L22.7,13.35C22.92,13.14 22.92,12.79 22.7,12.58L21.42,11.3C21.31,11.19 21.18,11.13 21.04,11.13M19.07,12.88L13,18.94V21H15.06L21.12,14.93L19.07,12.88Z" />
|
||||
</graphic>
|
||||
</Button>
|
||||
<Label text="Save recieved to:" />
|
||||
<Label fx:id="saveToLbl" />
|
||||
</children>
|
||||
</HBox>
|
||||
<Separator prefWidth="200.0" />
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label text="NS read buffer size:" />
|
||||
<TextField fx:id="readBufferSizeTf" />
|
||||
<Label text="(e.g. 512 or 4096)" />
|
||||
</children>
|
||||
</HBox>
|
||||
<RadioButton fx:id="readOnStartRb" mnemonicParsing="false" text="Read on start" />
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<RadioButton fx:id="writeOnStartRb" mnemonicParsing="false" text="Write on start" />
|
||||
<Button fx:id="fileToSendBtn" mnemonicParsing="false">
|
||||
<graphic>
|
||||
<SVGPath content="M3,4C1.89,4 1,4.89 1,6V18A2,2 0 0,0 3,20H11V18.11L21,8.11V8C21,6.89 20.1,6 19,6H11L9,4H3M21.04,11.13C20.9,11.13 20.76,11.19 20.65,11.3L19.65,12.3L21.7,14.35L22.7,13.35C22.92,13.14 22.92,12.79 22.7,12.58L21.42,11.3C21.31,11.19 21.18,11.13 21.04,11.13M19.07,12.88L13,18.94V21H15.06L21.12,14.93L19.07,12.88Z" />
|
||||
</graphic>
|
||||
</Button>
|
||||
<Label fx:id="sendFileLbl" text="?" />
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" spacing="5.0">
|
||||
<children>
|
||||
<Button fx:id="startBtn" mnemonicParsing="false" text="Start" />
|
||||
<Button fx:id="stopBtn" mnemonicParsing="false" text="Stop" />
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</VBox>
|
||||
<TextArea fx:id="logArea" editable="false" />
|
||||
</items>
|
||||
</SplitPane>
|
||||
<AnchorPane>
|
||||
<children>
|
||||
<ProgressBar fx:id="progressBar" progress="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</AnchorPane>
|
BIN
src/main/resources/res/NotoMono-Regular.ttf
Normal file
BIN
src/main/resources/res/NotoMono-Regular.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/res/app_icon128x128.png
Normal file
BIN
src/main/resources/res/app_icon128x128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
src/main/resources/res/app_icon32x32.png
Normal file
BIN
src/main/resources/res/app_icon32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
BIN
src/main/resources/res/app_icon48x48.png
Normal file
BIN
src/main/resources/res/app_icon48x48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
BIN
src/main/resources/res/app_icon64x64.png
Normal file
BIN
src/main/resources/res/app_icon64x64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
442
src/main/resources/res/app_light.css
Normal file
442
src/main/resources/res/app_light.css
Normal file
|
@ -0,0 +1,442 @@
|
|||
@font-face {
|
||||
src: url("NotoMono-Regular.ttf");
|
||||
}
|
||||
.root{
|
||||
-fx-background: #f5f5f5;
|
||||
}
|
||||
|
||||
.button SVGPath{
|
||||
-fx-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
.button:hover SVGPath, .choice-box:hover SVGPath, .button:focused:hover SVGPath, .choice-box:focused:hover SVGPath, .button:pressed SVGPath, .button:pressed:hover SVGPath{
|
||||
-fx-fill: #ffffff;
|
||||
}
|
||||
.button{
|
||||
-fx-background-color: #ffffff;
|
||||
-fx-border-color: #0d98ba;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
-fx-border-width: 1;
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
.button:disabled SVGPath{
|
||||
-fx-fill: #bbbbbb;
|
||||
}
|
||||
.button:disabled {
|
||||
-fx-opacity: 1.0 ;
|
||||
-fx-background-color: #959595;
|
||||
-fx-border-color: #959595;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
-fx-border-width: 1;
|
||||
-fx-text-fill: #bbbbbb;
|
||||
}
|
||||
|
||||
.button:hover, .choice-box:hover, .button:focused:hover, .choice-box:focused:hover{
|
||||
-fx-background-color: #0d98ba;
|
||||
-fx-border-color: #0d98ba;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
-fx-border-width: 1;
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
.button:focused, .choice-box:focused{
|
||||
-fx-background-color: #d0d0d0;
|
||||
-fx-border-color: #0d98ba;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
-fx-border-width: 1;
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
.button:pressed, .button:pressed:hover{
|
||||
-fx-background-color: #007cad;
|
||||
-fx-border-color: #007cad;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
-fx-border-width: 1;
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
// -========================+ Button RED =====================-
|
||||
.buttonRed SVGPath{
|
||||
-fx-fill: #e34234;
|
||||
}
|
||||
.buttonRed{
|
||||
-fx-background-color: #ffffff;
|
||||
-fx-border-color: #e34234;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
-fx-border-width: 1;
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
.buttonRed:hover, .buttonRed:focused:hover{
|
||||
-fx-background-color: #e34234;
|
||||
-fx-border-color: #e34234;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
-fx-border-width: 1;
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
.buttonRed:focused{
|
||||
-fx-background-color: #d0d0d0;
|
||||
-fx-border-color: #cc0605;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
-fx-border-width: 1;
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
.buttonRed:pressed, .buttonRed:pressed:hover{
|
||||
-fx-background-color: #cc0605;
|
||||
-fx-border-color: #cc0605;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
-fx-border-width: 1;
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
// -========================+ TextArea =====================-
|
||||
.text-area{
|
||||
-fx-background-color: transparent;
|
||||
-fx-control-inner-background: #fefefe;
|
||||
-fx-font-family: "Noto Mono";
|
||||
-fx-background-radius: 3;
|
||||
-fx-border-color: #0d98ba;
|
||||
-fx-border-radius: 3;
|
||||
-fx-border-width: 2;
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
-fx-fit-to-width: true;
|
||||
-fx-background-color: transparent;
|
||||
-fx-box-border: transparent;
|
||||
}
|
||||
.progress-bar > .track {
|
||||
-fx-background-color: transparent;
|
||||
-fx-box-border: transparent;
|
||||
}
|
||||
.progress-bar > .bar {
|
||||
-fx-background-color: linear-gradient(to right, #00bce4, #ff5f53);
|
||||
-fx-background-radius: 2;
|
||||
-fx-background-insets: 1 1 2 1;
|
||||
-fx-padding: 0.23em;
|
||||
}
|
||||
|
||||
.dialog-pane {
|
||||
-fx-background-color: #fefefe;
|
||||
}
|
||||
.dialog-pane > .button-bar > .container{
|
||||
-fx-background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.dialog-pane > .label{
|
||||
-fx-padding: 10 5 10 5;
|
||||
}
|
||||
|
||||
.tool-bar{
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.special-pane-as-border{
|
||||
-fx-background-color: #2c2c2c;
|
||||
-fx-min-height: 1;
|
||||
}
|
||||
// -======================== Choice box =========================-
|
||||
.choice-box {
|
||||
-fx-background-color: #fefefe;
|
||||
-fx-border-color: #fefefe;
|
||||
-fx-border-radius: 3;
|
||||
-fx-border-width: 2;
|
||||
-fx-mark-color: #eea11e;
|
||||
-fx-effect: dropshadow(three-pass-box, #414a4c, 2, 0, 0, 0);
|
||||
}
|
||||
.choice-box > .label {
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
.choice-box:pressed, .choice-box:pressed:hover{
|
||||
-fx-background-color: #fefefe;
|
||||
-fx-border-color: #eea11e;
|
||||
-fx-border-radius: 3;
|
||||
-fx-border-width: 2;
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
// Background color of the whole context menu
|
||||
.choice-box .context-menu {
|
||||
-fx-background-color: #fefefe;
|
||||
}
|
||||
|
||||
// Focused item background color in the list
|
||||
.choice-box .context-menu .menu-item:focused {
|
||||
-fx-background-color: #eea11e;
|
||||
|
||||
}
|
||||
.choice-box .context-menu .menu-item:focused .label {
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
// -======================== TAB PANE =========================-
|
||||
/*
|
||||
.tab-pane .tab SVGPath{
|
||||
-fx-fill: #2c2c2c; // OK
|
||||
}
|
||||
.tab-pane .tab:selected SVGPath{
|
||||
-fx-fill: #1dacd6; // OK
|
||||
}
|
||||
.tab-pane .tab{
|
||||
-fx-background-color: #fefefe; //ok
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
-fx-border-radius: 0 0 0 0;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
-fx-border-color: #fefefe; //OK
|
||||
}
|
||||
|
||||
.tab-pane .tab:selected{
|
||||
-fx-background-color: #ffefd5; // OK
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
-fx-border-radius: 0 0 0 0;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
-fx-border-color: #9aceeb; // OK
|
||||
}
|
||||
|
||||
.tab-pane > .tab-header-area {
|
||||
-fx-background-insets: 0.0;
|
||||
-fx-padding: 5 5 5 5 ;
|
||||
}
|
||||
|
||||
.tab-pane > .tab-header-area > .tab-header-background
|
||||
{
|
||||
-fx-background-color: #fefefe; // OK
|
||||
|
||||
}
|
||||
.tab-pane > .tab-header-area > .headers-region > .tab {
|
||||
-fx-padding: 10;
|
||||
}
|
||||
*/
|
||||
// -======================== TAB PANE =========================-
|
||||
.tab-pane .tab SVGPath{
|
||||
-fx-fill: #2c2c2c;
|
||||
}
|
||||
.tab-pane .tab:selected SVGPath, .tab-pane .tab:hover SVGPath{
|
||||
-fx-fill: #ffffff;
|
||||
}
|
||||
|
||||
.tab-pane .tab .label{
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
.tab-pane .tab{
|
||||
-fx-background-color: #f5f5f5;
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
.tab-pane .tab:selected .label{
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
.tab-pane .tab:selected{
|
||||
-fx-background-color: #007cad;
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
.tab-pane .tab:hover .label{
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
.tab-pane .tab:hover{
|
||||
-fx-background-color: #0d98ba;
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
.tab-pane > .tab-header-area {
|
||||
-fx-background-insets: 0.0;
|
||||
-fx-padding: 5 5 5 5 ;
|
||||
}
|
||||
|
||||
.tab-pane > .tab-header-area > .tab-header-background
|
||||
{
|
||||
-fx-background-color: #f5f5f5;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
-fx-border-color: #959595;
|
||||
}
|
||||
.tab-pane > .tab-header-area > .headers-region > .tab {
|
||||
-fx-padding: 10;
|
||||
}
|
||||
|
||||
// Special colors for in-file sub-files
|
||||
.tab-pane .tab-sub:selected{
|
||||
-fx-background-color: #b90078;
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
.tab-pane .tab-sub:hover{
|
||||
-fx-background-color: #df0091;
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
// -=========================== TABLE ======================-
|
||||
.table-view {
|
||||
-fx-background-color: #fefefe;
|
||||
-fx-background-image: url(app_logo.png);
|
||||
-fx-background-position: center;
|
||||
-fx-background-repeat: no-repeat;
|
||||
-fx-background-radius: 3;
|
||||
-fx-border-color: #0d98ba;
|
||||
-fx-border-radius: 3;
|
||||
-fx-border-width: 2;
|
||||
}
|
||||
.table-view .arrow {
|
||||
-fx-mark-color: #2c2c2c ;
|
||||
}
|
||||
.table-view .column-header {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-width: 0 1 2 0;
|
||||
-fx-border-color: #b0b0b0;
|
||||
}
|
||||
.table-view .column-header-background .label{
|
||||
-fx-background-color: transparent;
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
.table-view .column-header-background, .table-view .filler{
|
||||
-fx-background-color: #fefefe;
|
||||
}
|
||||
|
||||
.table-view .table-cell{
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
.table-row-cell, .table-row-cell:filled:selected, .table-row-cell:selected{
|
||||
-fx-background-color: -fx-table-cell-border-color, #f0fff0;
|
||||
-fx-background-insets: 0, 0 0 1 0;
|
||||
-fx-padding: 0.0em; /* 0 */
|
||||
-fx-table-cell-border-color: #b0b0b0;
|
||||
}
|
||||
.table-row-cell .text, .table-row-cell:odd .text {
|
||||
-fx-fill: #2c2c2c;
|
||||
}
|
||||
.table-row-cell:filled:selected .text, .table-row-cell:odd:filled:selected .text{
|
||||
-fx-fill: #2c2c2c;
|
||||
-fx-font-weight: bold
|
||||
}
|
||||
.table-row-cell:odd, .table-row-cell:odd:filled:selected, .table-row-cell:odd:selected{
|
||||
-fx-background-color: -fx-table-cell-border-color, #fefefe;
|
||||
-fx-background-insets: 0, 0 0 1 0;
|
||||
-fx-padding: 0.0em; /* 0 */
|
||||
-fx-table-cell-border-color: #b0b0b0;
|
||||
}
|
||||
// -========================== Context menu =====================-
|
||||
.context-menu {
|
||||
-fx-background-color: #fefefe;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
.context-menu .menu-item .label {
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
.context-menu .menu-item:focused .label {
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
// -========================== Text Field =====================-
|
||||
.text-field {
|
||||
-fx-border-color: #289de8;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
-fx-background-color: transparent;
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
.text-field:focused {
|
||||
-fx-border-color: #e82382;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
-fx-background-color: transparent;
|
||||
-fx-text-fill: #e82382;
|
||||
}
|
||||
|
||||
.customMainGrid {
|
||||
-fx-border-color: #191919;
|
||||
-fx-border-width: 1;
|
||||
}
|
||||
.customTitleGrid {
|
||||
-fx-background-color: #191919, #f0fff0;
|
||||
-fx-background-insets: 0, 1;
|
||||
}
|
||||
.customGrid {
|
||||
-fx-background-color: #191919, #f0f0f0;
|
||||
-fx-background-insets: 0, 1;
|
||||
}
|
||||
// -======================== Titiled Pane ========================-
|
||||
.titled-pane
|
||||
{
|
||||
-fx-text-fill: #000000;
|
||||
}
|
||||
|
||||
.titled-pane:focused
|
||||
{
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
|
||||
.titled-pane > .title
|
||||
{
|
||||
-fx-background-color: #efebe6;
|
||||
-fx-background-insets: 0, 1, 2;
|
||||
-fx-background-radius: 5 5 0 0, 4 4 0 0, 3 3 0 0;
|
||||
-fx-padding: 3 11 5 11;
|
||||
-fx-border-width: 1;
|
||||
-fx-border-radius: 5 5 0 0, 4 4 0 0, 3 3 0 0;
|
||||
-fx-border-color: #c8c8c8;
|
||||
}
|
||||
|
||||
.titled-pane:focused > .title
|
||||
{
|
||||
-fx-background-color: #d5713f;
|
||||
-fx-background-insets: 0, 1, 2;
|
||||
-fx-background-radius: 5 5 0 0, 4 4 0 0, 3 3 0 0;
|
||||
-fx-padding: 3 11 5 11;
|
||||
-fx-border-width: 1;
|
||||
-fx-border-radius: 5 5 0 0, 4 4 0 0, 3 3 0 0;
|
||||
-fx-border-color: #c8c8c8;
|
||||
}
|
||||
|
||||
.titled-pane > .title > .arrow-button
|
||||
{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-insets: 0;
|
||||
-fx-background-radius: 0;
|
||||
-fx-padding: 0 3 0 0;
|
||||
}
|
||||
|
||||
.titled-pane > .title > .arrow-button .arrow
|
||||
{
|
||||
-fx-background-color: #575757, #575757;
|
||||
-fx-background-insets: 1 0 -1 0, 0;
|
||||
-fx-padding: 3 3.75 3 3.75;
|
||||
-fx-shape: "M 0 0 h 7 l -3.5 4 z";
|
||||
}
|
||||
|
||||
.titled-pane:collapsed > .title > .arrow-button .arrow
|
||||
{
|
||||
-fx-rotate: -90;
|
||||
}
|
||||
|
||||
.titled-pane:focused > .title > .arrow-button .arrow
|
||||
{
|
||||
-fx-background-color: white, white;
|
||||
}
|
||||
|
||||
.regionFolder {
|
||||
-fx-shape: "M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z";
|
||||
-fx-background-color: #ffbf00;
|
||||
-fx-min-height: 17.0;
|
||||
-fx-min-width: 17.5;
|
||||
}
|
||||
.regionFile {
|
||||
-fx-shape: "M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z";
|
||||
-fx-background-color: #e54d1e;
|
||||
-fx-min-height: 17.0;
|
||||
-fx-min-width: 13;
|
||||
}
|
Loading…
Reference in a new issue