From 72d5df2c706742612f3a040a62b2d93efa04598d Mon Sep 17 00:00:00 2001 From: rattatwinko Date: Thu, 21 May 2026 17:05:59 +0200 Subject: [PATCH] add some rsys utils (mostly just linux modified) --- src/main/java/com/rdesk/Main.java | 6 +- .../applications/system/rsys/KbChanger.java | 94 +++++++++++++++++++ .../com/rdesk/kernel/rsys/KbInterface.java | 80 ++++++++++++++++ 3 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/rdesk/applications/system/rsys/KbChanger.java create mode 100644 src/main/java/com/rdesk/kernel/rsys/KbInterface.java diff --git a/src/main/java/com/rdesk/Main.java b/src/main/java/com/rdesk/Main.java index cd16d7d..12a8402 100644 --- a/src/main/java/com/rdesk/Main.java +++ b/src/main/java/com/rdesk/Main.java @@ -8,6 +8,7 @@ import com.rdesk.applications.system.Exit; import com.rdesk.applications.productivity.Notes; import com.rdesk.applications.system.TaskManager; import com.rdesk.applications.system.filehaj.FileExplorerApp; +import com.rdesk.applications.system.rsys.KbChanger; import com.rdesk.kernel.*; import com.rdesk.kernel.launcher.AppLauncher; @@ -84,14 +85,17 @@ public class Main { } private static void registerSystemApps(AppLauncher launcher) { - + // productivity launcher.addApp(new Notes(), "Productivity"); launcher.addApp(new TabbedBrowser(), "Productivity"); launcher.addApp(new CodeDesk(), "Productivity"); launcher.addApp(new Calculator(), "Productivity"); + // entertainment launcher.addApp(new Xkcd(), "Entertainment"); + // System apps launcher.addApp(new Exit(), "System"); launcher.addApp(new TaskManager(), "System"); launcher.addApp(new FileExplorerApp(), "System"); + launcher.addApp(new KbChanger(), "System"); } } \ No newline at end of file diff --git a/src/main/java/com/rdesk/applications/system/rsys/KbChanger.java b/src/main/java/com/rdesk/applications/system/rsys/KbChanger.java new file mode 100644 index 0000000..4226c92 --- /dev/null +++ b/src/main/java/com/rdesk/applications/system/rsys/KbChanger.java @@ -0,0 +1,94 @@ +package com.rdesk.applications.system.rsys; + +import com.rdesk.kernel.DesktopApp; +import com.rdesk.kernel.Kernel; +import com.rdesk.kernel.rsys.KbInterface; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +public class KbChanger implements DesktopApp { + private static final String[] LAYOUTS = { + "us", "uk", "de", "fr", "es", "it", "ru", "jp", "br", "cz" + }; + + @Override + public String getId() { + return "kbchanger"; + } + + @Override + public String getName() { + return "KbChanger"; + } + + @Override + public JInternalFrame createWindow(Kernel kernel) { + JInternalFrame frame = new JInternalFrame( + "Keyboard Layout", + true, // resizable + true, // closable + true, // maximizable + true // iconifiable + ); + + frame.setSize(420, 200); + frame.setLayout(new BorderLayout(8, 8)); + frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + + JPanel top = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 12)); + top.add(new JLabel("Layout:")); + + JComboBox layoutCombo = new JComboBox<>(LAYOUTS); + layoutCombo.setEditable(false); + top.add(layoutCombo); + + JButton applyBtn = new JButton("Apply"); + top.add(applyBtn); + + frame.add(top, BorderLayout.NORTH); + + JPanel center = new JPanel(new BorderLayout(6, 6)); + JLabel hint = new JLabel("Type here to test the selected layout:"); + center.add(hint, BorderLayout.NORTH); + + JTextField testField = new JTextField(); + center.add(testField, BorderLayout.CENTER); + + JLabel status = new JLabel("Last applied: (none)"); + status.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); + center.add(status, BorderLayout.SOUTH); + + frame.add(center, BorderLayout.CENTER); + + KbInterface kb = new KbInterface(); + + applyBtn.addActionListener((ActionEvent e) -> { + String selected = (String) layoutCombo.getSelectedItem(); + if (selected == null || selected.trim().isEmpty()) { + JOptionPane.showMessageDialog(frame, "Please select a layout.", "Keyboard Layout", JOptionPane.WARNING_MESSAGE); + return; + } + + kb.setKbLayout(selected); + + status.setText("Last applied: " + selected); + SwingUtilities.invokeLater(testField::requestFocusInWindow); + }); + + testField.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + applyBtn.doClick(); + } + } + }); + + frame.setVisible(true); + return frame; + } +} diff --git a/src/main/java/com/rdesk/kernel/rsys/KbInterface.java b/src/main/java/com/rdesk/kernel/rsys/KbInterface.java new file mode 100644 index 0000000..9a1208c --- /dev/null +++ b/src/main/java/com/rdesk/kernel/rsys/KbInterface.java @@ -0,0 +1,80 @@ + +package com.rdesk.kernel.rsys; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.win32.W32APIOptions; + +import javax.swing.*; + +public class KbInterface { + + private static final java.util.Map LAYOUT_TO_KLID = java.util.Map.ofEntries( + java.util.Map.entry("us", "00000409"), + java.util.Map.entry("uk", "00000809"), + java.util.Map.entry("de", "00000407"), + java.util.Map.entry("fr", "0000040C"), + java.util.Map.entry("es", "0000040A"), + java.util.Map.entry("it", "00000410"), + java.util.Map.entry("ru", "00000419"), + java.util.Map.entry("jp", "00000411"), + java.util.Map.entry("br", "00000416"), + java.util.Map.entry("cz", "00000405") + ); + + + private interface User32 extends Library { + User32 INSTANCE = Native.load("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS); + long LoadKeyboardLayoutA(String pwszKLID, int Flags); + } + + public void setKbLayout(String kbLayout) { + String os = System.getProperty("os.name").toLowerCase(); + try { + if (os.contains("win")) { + setWindowsLayout(kbLayout); + } else if (os.contains("nix") || os.contains("nux") || os.contains("aix") || os.contains("linux")) { + setLinuxLayout(kbLayout); + } else if (os.contains("mac")) { + showError("mac is too shitty for this"); + } else { + showError("what are you running?: " + os); + } + } catch (Exception ex) { + showError("The keyboard layout could not be set " + ex.getMessage()); + } + } + + private void setLinuxLayout(String kbLayout) throws Exception { + new ProcessBuilder("setxkbmap", kbLayout) + .inheritIO() + .start() + .waitFor(); + } + + private void setWindowsLayout(String kbLayout) { + String klid = kbLayout; + if (!kbLayout.matches("[0-9A-Fa-f]{8}")) { + klid = LAYOUT_TO_KLID.getOrDefault(kbLayout.toLowerCase(), null); + if (klid == null) { + showError("Unknown Windows layout: " + kbLayout); + return; + } + } + + int KLF_ACTIVATE = 0x00000001; + long result = User32.INSTANCE.LoadKeyboardLayoutA(klid, KLF_ACTIVATE); + if (result == 0) { + showError("Failed to load keyboard layout " + klid); + } + } + + private void showError(String message) { + JOptionPane.showMessageDialog( + null, + message, + "Keyboard Layout", + JOptionPane.ERROR_MESSAGE + ); + } +}