From a353a418d7ba96403c11d221251a7629fd925237 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Tue, 16 Dec 2025 18:39:20 +0100 Subject: [PATCH] load application properties in java, not in the C toolkit code --- .../src/main/java/de/unixwork/ui/Toolkit.java | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/ui-java/src/main/java/de/unixwork/ui/Toolkit.java b/ui-java/src/main/java/de/unixwork/ui/Toolkit.java index 1bb9303..0e2a729 100644 --- a/ui-java/src/main/java/de/unixwork/ui/Toolkit.java +++ b/ui-java/src/main/java/de/unixwork/ui/Toolkit.java @@ -1,17 +1,24 @@ package de.unixwork.ui; +import java.io.*; import java.lang.foreign.*; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; +import java.util.Properties; public class Toolkit { private static Toolkit instance; private Application app; + private Properties appProperties = new Properties(); + byte[] propertiesData; + private HashMap toplevelObjects = new HashMap<>(); private HashMap documents = new HashMap<>(); private HashMap contexts = new HashMap<>(); // TODO: maybe we can replace the UiObject and Document maps with just this context map @@ -57,11 +64,32 @@ public class Toolkit { private ArrayList sourceListMenuBuilderCache = new ArrayList<>(); private Toolkit(String appName) { + try { + loadAppProperties(appName); + } catch (IOException e) { + e.printStackTrace(); + } + // load shared library System.loadLibrary("uitk"); linker = Linker.nativeLinker(); lib = SymbolLookup.loaderLookup(); + // set properties data if available + if(propertiesData != null) { + MemorySegment ui_set_properties_data_addr = lib.find("ui_set_properties_data").orElseThrow(); + MethodHandle ui_set_properties_data = linker.downcallHandle(ui_set_properties_data_addr, FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_LONG)); + + try (Arena arena = Arena.ofShared()){ + MemorySegment segment = arena.allocate(propertiesData.length); + segment.asByteBuffer().put(propertiesData); + ui_set_properties_data.invoke(segment, (long)propertiesData.length); + } catch (Throwable e) { + throw new RuntimeException(e); + } + propertiesData = null; + } + // get init function MemorySegment ui_init_addr = lib.find("ui_init").orElseThrow(); FunctionDescriptor ui_init_sig = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS); @@ -89,6 +117,34 @@ public class Toolkit { } } + public void loadAppProperties(String appName) throws IOException { + String path = Toolkit.getAppConfigPath(appName); + if(path == null) { + return; + } + if(path != null) { + File f = new File(path); + if(!f.exists()) { + return; + } + try { + propertiesData = Files.readAllBytes(Path.of(path)); + } catch (IOException e) { + throw e; + } + + try (ByteArrayInputStream in = new ByteArrayInputStream(propertiesData)) { + appProperties.load(in); + } catch (IOException e) { + throw e; + } + } + } + + public Properties getAppProperties() { + return appProperties; + } + public void setIsObjRegEnabled(boolean value) { isObjRegEnabled = value; } @@ -719,6 +775,41 @@ public class Toolkit { } } + public static String getAppDir(String appName) { + if(appName == null || appName.isEmpty()) { + return null; + } + + String home = System.getProperty("user.home"); + String os = System.getProperty("os.name"); + if(os.startsWith("Windows")) { + // windows + return home + "\\AppData\\Roaming\\" + appName; + } else if(os.startsWith("Mac OS X")) { + // macOS + return home + "/Library/Application Support/" + appName; + } + + // unix + String xdgConfigHome = System.getenv("XDG_CONFIG_HOME"); + if(xdgConfigHome != null) { + if(xdgConfigHome.endsWith("/")) { + xdgConfigHome = xdgConfigHome.substring(0, xdgConfigHome.length()-1); + } + return xdgConfigHome + "/" + appName; + } else { + return home + "/.config/" + appName; + } + } + + public static String getAppConfigPath(String appName) { + String configPath = getAppDir(appName); + if(configPath == null) { + return null; + } + return configPath + File.separator + "application.properties"; + } + public static String getConfigPath() { ToolkitFuncs ui = ToolkitFuncs.getInstance(); try { -- 2.47.3