Skip to content

Commit 99dbbd0

Browse files
authored
Merge pull request #1 from umjammer/0.0.2
0.0.2
2 parents c3fdb88 + 76215b8 commit 99dbbd0

File tree

5 files changed

+44
-129
lines changed

5 files changed

+44
-129
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77

88
<img src="https://github.com/umjammer/vavi-apps-hub/assets/493908/5efff428-15df-46bb-a7b0-929e31caf3c2" width="128" alt="hub logo" />
99

10-
My Hub ❤
10+
🌐 hub for plugins that controls a computer
1111

1212
### plugins
1313

1414
* remote notificator
1515
* remote trackpad (wip)
16-
* gamepad binder
16+
* 🏅 gamepad binder (Minecraft, MuseScore3)
1717
* hand gesture recognizer (tbd)
1818

1919
## Install
@@ -63,9 +63,11 @@ My Hub ❤
6363
## TODO
6464

6565
* ~~hub for notification center over inet~~
66-
* hub for remote mouse input (wip) -> this websocket server
67-
* ~~apple remote event?~~ -> this rest server
66+
* ~~hub for remote mouse input~~ -> this websocket server (done)
67+
* touchpad (wip)
68+
* ~~apple remote event?~~ -> this rest server (done)
6869
* ~~coexistence websocket and jersey on jetty~~ see [Main.java](src/main/java/vavi/apps/hub/Main.java)
70+
* gamepad configuration, dsl?, json?
6971

7072
---
7173
<sub>image by <a href="https://www.silhouette-illust.com/illust/49214">silhouette illust</a></sub>

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>vavi</groupId>
77
<artifactId>vavi-apps-hub</artifactId>
8-
<version>0.0.1</version>
8+
<version>0.0.2</version>
99

1010
<properties>
1111
<javapackager.name>Hub</javapackager.name>
@@ -176,7 +176,7 @@
176176
<dependency>
177177
<groupId>com.github.umjammer</groupId> <!-- vavi / com.github.umjammer -->
178178
<artifactId>vavi-awt-joystick</artifactId>
179-
<version>0.0.7</version>
179+
<version>0.0.8</version>
180180
</dependency>
181181

182182
<dependency>

src/main/java/vavi/apps/hub/Tray.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ public class Tray implements Plugin {
3030
/** */
3131
private PopupMenu popup;
3232

33+
/** TODO generated automatically? */
3334
MenuItem gamepadItem;
3435

36+
/** TODO location should be at gamepad plugin */
3537
void gamepad(GenericEvent event) {
3638
if (gamepadItem == null) {
3739
gamepadItem = new MenuItem();

src/main/java/vavi/games/input/listener/MinecraftListener.java

Lines changed: 30 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,16 @@
1111
import java.awt.MouseInfo;
1212
import java.awt.Point;
1313
import java.awt.Rectangle;
14-
import java.util.Arrays;
1514
import java.util.NoSuchElementException;
1615
import java.util.concurrent.Executors;
1716
import java.util.concurrent.atomic.AtomicReference;
18-
import java.util.function.Consumer;
1917
import java.util.logging.Level;
2018

21-
import com.sun.jna.platform.mac.CoreFoundation.CFArrayRef;
22-
import com.sun.tools.attach.VirtualMachine;
23-
import com.sun.tools.attach.VirtualMachineDescriptor;
2419
import net.java.games.input.Event;
25-
import org.rococoa.Rococoa;
26-
import org.rococoa.cocoa.appkit.NSRunningApplication;
27-
import org.rococoa.cocoa.coregraphics.RococaRobot;
28-
import org.rococoa.cocoa.foundation.NSDictionary;
29-
import org.rococoa.cocoa.foundation.NSString;
20+
import vavi.games.input.listener.GamepadInputEventListener.AppInfo;
3021
import vavi.games.input.listener.GamepadInputEventListener.Context;
22+
import vavi.games.input.robot.Key;
23+
import vavi.games.input.robot.RococaRobot;
3124
import vavi.util.Debug;
3225
import vavi.util.event.GenericEvent;
3326

@@ -51,9 +44,7 @@
5144
import static org.rococoa.carbon.CarbonCoreLibrary.kVK_Space;
5245
import static org.rococoa.cocoa.coregraphics.CoreGraphicsLibrary.kCGMouseButtonLeft;
5346
import static org.rococoa.cocoa.coregraphics.CoreGraphicsLibrary.kCGMouseButtonRight;
54-
import static org.rococoa.cocoa.coregraphics.CoreGraphicsLibrary.kCGNullWindowID;
55-
import static org.rococoa.cocoa.coregraphics.CoreGraphicsLibrary.kCGWindowListOptionOnScreenOnly;
56-
import static org.rococoa.cocoa.coregraphics.CoreGraphicsLibrary.library;
47+
import static vavi.games.input.helper.JavaVMAppInfo.getPidByMainClassName;
5748

5849

5950
/**
@@ -66,15 +57,35 @@ public class MinecraftListener extends GamepadAdapter {
6657

6758
private static final String bundleId = "com.mojang.Minecraft";
6859

60+
/** minecraft launchers descriptor#dusplayName */
61+
private static final String[] mcLaunchers = {
62+
"net.minecraft.client.main.Main", // mc launcher -> original
63+
"net.fabricmc.loader.impl.launch.knot.KnotClient", // mc launcher -> fabric
64+
"org.prismlauncher.EntryPoint" // prism launcher
65+
};
66+
6967
private long prevForBounds;
7068

7169
@Override
72-
public boolean match(NSRunningApplication a) {
70+
public boolean match(AppInfo a) {
7371
try {
74-
if (a.processIdentifier().intValue() == getMcLauncherPid()) {
72+
if (a.pid() == getPidByMainClassName(mcLaunchers)) {
7573
if (System.currentTimeMillis() - prevForBounds > 20 * 1000) {
7674
prevForBounds = System.currentTimeMillis();
77-
Executors.newSingleThreadScheduledExecutor().submit(() -> retrieveBounds(a));
75+
Executors.newSingleThreadScheduledExecutor().submit(() -> {
76+
Rectangle b = a.bounds();
77+
if (b != null) {
78+
Rectangle r = bounds.get();
79+
if (r == null) {
80+
bounds.set(b);
81+
} else {
82+
r.setBounds(b);
83+
}
84+
//Debug.println("minecraft window found: " + r);
85+
// } else {
86+
//Debug.println("no minecraft window found.");
87+
}
88+
});
7889
}
7990
return true;
8091
}
@@ -84,48 +95,6 @@ public boolean match(NSRunningApplication a) {
8495
return false;
8596
}
8697

87-
/** @after {@link #bounds} */
88-
private void retrieveBounds(NSRunningApplication a) {
89-
CFArrayRef array = library.CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
90-
//Debug.println("windows: " + array.getCount());
91-
for (int i = 0; i < array.getCount(); i++) {
92-
NSDictionary dic = Rococoa.toNSDictionary(array.getValueAtIndex(i));
93-
if (Integer.parseInt(dic.get(NSString.stringWithString("kCGWindowOwnerPID")).toString()) == a.processIdentifier().intValue()) {
94-
NSDictionary rect = Rococoa.cast(dic.get(NSString.stringWithString("kCGWindowBounds")), NSDictionary.class);
95-
int x = Integer.parseInt(rect.get(NSString.stringWithString("X")).toString());
96-
int y = Integer.parseInt(rect.get(NSString.stringWithString("Y")).toString());
97-
int width = Integer.parseInt(rect.get(NSString.stringWithString("Width")).toString());
98-
int height = Integer.parseInt(rect.get(NSString.stringWithString("Height")).toString());
99-
Rectangle r = bounds.get();
100-
if (r == null) {
101-
bounds.set(new Rectangle(x, y, width, height));
102-
} else {
103-
r.setBounds(x, y, width, height);
104-
}
105-
//Debug.println("minecraft window found: " + r);
106-
return;
107-
}
108-
}
109-
//Debug.println("no minecraft window found.");
110-
}
111-
112-
/** minecraft launchers descriptor#dusplayName */
113-
private static final String[] mcLaunchers = {
114-
"net.minecraft.client.main.Main", // mc launcher -> original
115-
"net.fabricmc.loader.impl.launch.knot.KnotClient", // mc launcher -> fabric
116-
"org.prismlauncher.EntryPoint" // prism launcher
117-
};
118-
119-
/** minecraft launchers pid which displayName contains one of those */
120-
private static int getMcLauncherPid() {
121-
for (VirtualMachineDescriptor descriptor : VirtualMachine.list()) {
122-
if (Arrays.asList(mcLaunchers).contains(descriptor.displayName())) {
123-
return Integer.decode(descriptor.id());
124-
}
125-
}
126-
throw new NoSuchElementException("minecraft might not run");
127-
}
128-
12998
// ----
13099

131100
private final RococaRobot robot = new RococaRobot();
@@ -146,7 +115,6 @@ private static int getMcLauncherPid() {
146115
private final AtomicReference<Rectangle> bounds = new AtomicReference<>();
147116

148117
/**
149-
* @before {@link #retrieveBounds}
150118
* @after {@link #point}
151119
*/
152120
private void normalizePoint() {
@@ -164,32 +132,6 @@ private void normalizePoint() {
164132
}
165133
}
166134

167-
static class Key {
168-
final int code;
169-
final Consumer<Integer> pressAction;
170-
final Consumer<Integer> releaseAction;
171-
boolean pressed;
172-
173-
public Key(int code, Consumer<Integer> pressAction, Consumer<Integer> releaseAction) {
174-
this.code = code;
175-
this.pressAction = pressAction;
176-
this.releaseAction = releaseAction;
177-
}
178-
179-
void press() {
180-
if (!pressed) {
181-
pressAction.accept(code);
182-
pressed = true;
183-
}
184-
}
185-
void release() {
186-
if (pressed) {
187-
releaseAction.accept(code);
188-
pressed = false;
189-
}
190-
}
191-
}
192-
193135
class RobotKey extends Key {
194136
RobotKey(int code) {
195137
super(code, robot::keyPress, robot::keyRelease);
@@ -198,38 +140,7 @@ class RobotKey extends Key {
198140

199141
class RobotKey2 extends Key {
200142
RobotKey2(int code) {
201-
super(code, robot::keyPress2, robot::keyRelease2);
202-
}
203-
}
204-
205-
@FunctionalInterface
206-
interface TriConsumer<T, U, V> {
207-
void accept(T t, U u, V v);
208-
}
209-
210-
static class KeyWithCoordinate {
211-
final int code;
212-
final TriConsumer<Integer, Integer, Integer> pressActionWithCoordinat;
213-
final TriConsumer<Integer, Integer, Integer> releaseActionWithCoordinat;
214-
boolean pressed;
215-
216-
public KeyWithCoordinate(int code, TriConsumer<Integer, Integer, Integer> pressActionWithCoordinate, TriConsumer<Integer, Integer, Integer> releaseActionWithCoordinate) {
217-
this.code = code;
218-
this.pressActionWithCoordinat = pressActionWithCoordinate;
219-
this.releaseActionWithCoordinat = releaseActionWithCoordinate;
220-
}
221-
222-
void press(int x, int y) {
223-
if (!pressed) {
224-
pressActionWithCoordinat.accept(code, x, y);
225-
pressed = true;
226-
}
227-
}
228-
void release(int x, int y) {
229-
if (pressed) {
230-
releaseActionWithCoordinat.accept(code, x, y);
231-
pressed = false;
232-
}
143+
super(code, robot::keyPressRaw, robot::keyReleaseRaw);
233144
}
234145
}
235146

@@ -580,9 +491,9 @@ public void onButton14(Event e) {
580491
@Override
581492
public void after() {
582493
if (moved) {
583-
robot.mouseMove2(dx, dy);
494+
robot.mouseMoveOnlyAccel(dx, dy);
584495
normalizePoint();
585-
robot.mouseMove0(point.x, point.y);
496+
robot.mouseMoveOnlyLocation(point.x, point.y);
586497
}
587498
}
588499
}

src/main/java/vavi/games/input/listener/MuseScoreListener.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
package vavi.games.input.listener;
88

99
import net.java.games.input.Event;
10-
import org.rococoa.cocoa.appkit.NSRunningApplication;
11-
import org.rococoa.cocoa.coregraphics.RococaRobot;
10+
import vavi.games.input.listener.GamepadInputEventListener.AppInfo;
1211
import vavi.games.input.listener.GamepadInputEventListener.Context;
12+
import vavi.games.input.robot.RococaRobot;
1313
import vavi.util.Debug;
1414
import vavi.util.event.GenericEvent;
1515

@@ -33,8 +33,8 @@ public class MuseScoreListener extends GamepadAdapter {
3333
private static final String bundleId = "org.musescore.MuseScore";
3434

3535
@Override
36-
public boolean match(NSRunningApplication a) {
37-
return a.bundleIdentifier().equals(bundleId);
36+
public boolean match(AppInfo a) {
37+
return a.id().equals(bundleId);
3838
}
3939

4040
private Context context;

0 commit comments

Comments
 (0)