diff --git a/README.md b/README.md
index ff86283..85c9bc7 100644
--- a/README.md
+++ b/README.md
@@ -130,31 +130,16 @@ Feel free to use the classes `lc.kra.system.keyboard.GobalKeyboardHook` and `lc.
The `LibraryLoader` will first attempt to load the native libraries from the `java.library.path` and fall back checking the archives `/lc/kra/system/lib` package, if no libraries where found.
### Maven Dependency
-You can include `system-hook` from this GitHub repository by adding this dependency to your `pom.xml`:
+You can include `system-hook` as a dependency from Maven Central by adding it to your `pom.xml`:
```xml
lc.kra.systemsystem-hook
- 3.5
+ 3.8
```
-Additionally you will have to add the following repository to your `pom.xml`:
-
-```xml
-
-
- system-hook-mvn-repo
- https://raw.github.com/kristian/system-hook/mvn-repo/
-
- true
- always
-
-
-
-```
-
Build
-----
diff --git a/appveyor.yml b/appveyor.yml
index 5ee176e..07edbe4 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 3.5.{build}
+version: 3.8.{build}
branches:
only:
diff --git a/build.xml b/build.xml
index eede54a..74356a0 100644
--- a/build.xml
+++ b/build.xml
@@ -103,7 +103,7 @@ SOFTWARE.
-
+
diff --git a/pom.xml b/pom.xml
index 39de76a..bc1a7af 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,9 +1,12 @@
-4.0.0lc.kra.systemsystem-hook
- 3.5
+ 3.8
+
+ Java System HookGlobal Keyboard / Mouse Hook for Java applications.https://github.com/kristian/system-hook
@@ -14,9 +17,9 @@
- deploy.repo
- Staging Repository
- file://${project.build.directory}/mvn-repo
+ ossrh
+ Maven Central
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
@@ -51,7 +54,7 @@
-
+
maven-compiler-plugin
@@ -61,18 +64,7 @@
1.6
-
-
- com.github.maven-nar
- nar-maven-plugin
- 3.5.2
- true
-
-
- true
-
-
-
+
org.apache.maven.pluginsmaven-antrun-plugin
@@ -85,7 +77,7 @@
run
-
+
@@ -134,55 +126,118 @@
-
+
org.apache.maven.plugins
- maven-jar-plugin
- 2.6
-
-
- lc/kra/system/keyboard/example/**
- lc/kra/system/mouse/example/**
-
+ maven-jar-plugin
+ 2.6
+
+
+ lc/kra/system/keyboard/example/**
+ lc/kra/system/mouse/example/**
+
-
+
maven-deploy-plugin
- 2.8.1
+ 2.8.2
+
+
+ default-deploy
+
+ deploy
+
+ deploy
+
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ 1.6.8
+
+
+ default-deploy
+ deploy
+
+ deploy
+
+
+
- deploy.repo.repo::default::file://${project.build.directory}/mvn-repo
+ ossrh
+ https://oss.sonatype.org/
+ true
+ true
- com.github.github
- site-maven-plugin
- 0.11
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.0
+
+
+ attach-sources
+ verify
+
+ jar-no-fork
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.2.0
- Maven artifacts for ${project.version}
- true
- ${project.build.directory}/mvn-repo
- refs/heads/mvn-repo
- true
-
- **/*
-
- system-hook
- kristian
+ UTF-8
+ 1.6
+ attach-javadoc
- site
+ jar
- deploy
+
+
+ release-sign-artifacts
+
+
+ performRelease
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+
+
+
MIT License
diff --git a/src/main/java/lc/kra/system/LibraryLoader.java b/src/main/java/lc/kra/system/LibraryLoader.java
index 3354c5b..66b80cc 100644
--- a/src/main/java/lc/kra/system/LibraryLoader.java
+++ b/src/main/java/lc/kra/system/LibraryLoader.java
@@ -37,9 +37,8 @@ public class LibraryLoader {
private static boolean libraryLoad;
/**
- * Tries to laod the library with the given name
+ * Tries to load the system hook library with the given name
*
- * @param name The name of the library to load
* @throws UnsatisfiedLinkError Thrown in case loading the library fails
*/
public static synchronized void loadLibrary() throws UnsatisfiedLinkError {
diff --git a/src/main/java/lc/kra/system/keyboard/GlobalKeyboardHook.java b/src/main/java/lc/kra/system/keyboard/GlobalKeyboardHook.java
index a398ea5..a68a4be 100644
--- a/src/main/java/lc/kra/system/keyboard/GlobalKeyboardHook.java
+++ b/src/main/java/lc/kra/system/keyboard/GlobalKeyboardHook.java
@@ -36,8 +36,10 @@
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_RWIN;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_SHIFT;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;
@@ -57,6 +59,9 @@ public class GlobalKeyboardHook {
private boolean menuPressed, shiftPressed, controlPressed, winPressed, extendedKey;
private List listeners = new CopyOnWriteArrayList();
+
+ private Set heldDownKeyCodes = new HashSet();
+
private Thread eventDispatcher = new Thread() {{
setName("Global Keyboard Hook Dispatcher");
setDaemon(true);
@@ -143,22 +148,55 @@ public GlobalKeyboardHook(GlobalHookMode mode) throws UnsatisfiedLinkError {
/**
* Invoke keyPressed (transition state TS_DOWN) for all registered listeners
*
- * @param event A global key event
+ * @param event a global key event
*/
private void keyPressed(GlobalKeyEvent event) {
+ heldDownKeyCodes.add(event.getVirtualKeyCode());
+
for(GlobalKeyListener listener:listeners)
listener.keyPressed(event);
}
+
/**
* Invoke keyReleased (transition state TS_UP) for all registered listeners
*
- * @param event A global key event
+ * @param event a global key event
*/
private void keyReleased(GlobalKeyEvent event) {
+ heldDownKeyCodes.remove(event.getVirtualKeyCode());
+
for(GlobalKeyListener listener:listeners)
listener.keyReleased(event);
}
+ /**
+ * Checks if the specified key is currently held down
+ *
+ * @param virtualKeyCode the virtual code of the key, use constants in {@link GlobalKeyEvent}
+ *
+ * @return true if the key is currently held down
+ */
+ public boolean isKeyHeldDown(int virtualKeyCode) {
+ return heldDownKeyCodes.contains(virtualKeyCode);
+ }
+
+
+ /**
+ * Checks if all the specified keys are currently held down
+ *
+ * @param virtualKeyCodes any number of specified key codes, use constants in {@link GlobalKeyEvent}
+ *
+ * @return true if all the specified keys are currently held down, false if any of the keys is not currently held down
+ */
+ public boolean areKeysHeldDown(int... virtualKeyCodes) {
+ for(int keyCode : virtualKeyCodes) {
+ if(!isKeyHeldDown(keyCode)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
/**
* Checks whether the keyboard hook is still alive and capturing inputs
*
diff --git a/src/main/java/lc/kra/system/keyboard/event/GlobalKeyAdapter.java b/src/main/java/lc/kra/system/keyboard/event/GlobalKeyAdapter.java
index a62a97e..1837fd5 100644
--- a/src/main/java/lc/kra/system/keyboard/event/GlobalKeyAdapter.java
+++ b/src/main/java/lc/kra/system/keyboard/event/GlobalKeyAdapter.java
@@ -23,12 +23,12 @@
public class GlobalKeyAdapter implements GlobalKeyListener {
/**
- * Invoked when a key has been pressed.
+ * @see GlobalKeyListener#keyPressed(GlobalKeyEvent)
*/
@Override public void keyPressed(GlobalKeyEvent event) {}
/**
- * Invoked when a key has been released.
+ * @see GlobalKeyListener#keyReleased(GlobalKeyEvent)
*/
@Override public void keyReleased(GlobalKeyEvent event) {}
}
\ No newline at end of file
diff --git a/src/main/java/lc/kra/system/keyboard/event/GlobalKeyEvent.java b/src/main/java/lc/kra/system/keyboard/event/GlobalKeyEvent.java
index c95c6ee..f89ead4 100644
--- a/src/main/java/lc/kra/system/keyboard/event/GlobalKeyEvent.java
+++ b/src/main/java/lc/kra/system/keyboard/event/GlobalKeyEvent.java
@@ -251,34 +251,34 @@ public GlobalKeyEvent(Object source, int virtualKeyCode, int transitionState, ch
* Returns the transition state (up or down) for this key event.
*
* @return either one of TS_UP or TS_DOWN.
- * @see {@link #TS_UP}
- * @see {@link #TS_DOWN}
+ * @see #TS_UP
+ * @see #TS_DOWN
*/
public int getTransitionState() { return transitionState; }
/**
- * Returns true if the menu key (alt) is pressed on the keyboard.
+ * @return true if the menu key (alt) is pressed on the keyboard.
*/
public boolean isMenuPressed() { return menuPressed; }
/**
- * Returns true if the shift key is pressed on the keyboard.
+ * @return true if the shift key is pressed on the keyboard.
*/
public boolean isShiftPressed() { return shiftPressed; }
/**
- * Returns true if the control key is pressed on the keyboard.
+ * @return true if the control key is pressed on the keyboard.
*/
public boolean isControlPressed() { return controlPressed; }
/**
- * Returns true if the windows key is pressed on the keyboard.
+ * @return true if the windows key is pressed on the keyboard.
*/
public boolean isWinPressed() { return winPressed; }
/**
- * Returns true if the menu/shift/control/win key pressed is an extended key.
+ * @return true if the menu/shift/control/win key pressed is an extended key.
*/
public boolean isExtendedKey() { return extendedKey; }
/**
- * Returns the handle of the keyboard the key was pressed on.
+ * @return the handle of the keyboard the key was pressed on.
*/
public long getDeviceHandle() { return deviceHandle; }
diff --git a/src/main/java/lc/kra/system/keyboard/event/GlobalKeyListener.java b/src/main/java/lc/kra/system/keyboard/event/GlobalKeyListener.java
index 7e6ecc2..09f2547 100644
--- a/src/main/java/lc/kra/system/keyboard/event/GlobalKeyListener.java
+++ b/src/main/java/lc/kra/system/keyboard/event/GlobalKeyListener.java
@@ -26,11 +26,15 @@
public interface GlobalKeyListener extends EventListener {
/**
* Invoked when a key has been pressed.
+ *
+ * @param event a global key event
*/
public void keyPressed(GlobalKeyEvent event);
/**
* Invoked when a key has been released.
+ *
+ * @param event a global key event
*/
public void keyReleased(GlobalKeyEvent event);
}
\ No newline at end of file
diff --git a/src/main/java/lc/kra/system/mouse/GlobalMouseHook.java b/src/main/java/lc/kra/system/mouse/GlobalMouseHook.java
index 99d44f0..56c63e7 100644
--- a/src/main/java/lc/kra/system/mouse/GlobalMouseHook.java
+++ b/src/main/java/lc/kra/system/mouse/GlobalMouseHook.java
@@ -146,7 +146,7 @@ public GlobalMouseHook(GlobalHookMode mode) throws UnsatisfiedLinkError {
/**
* Invoke mousePressed (transition state TS_DOWN) for all registered listeners
*
- * @param event A global mouse event
+ * @param event a global mouse event
*/
private void mousePressed(GlobalMouseEvent event) {
for(GlobalMouseListener listener:listeners)
@@ -155,7 +155,7 @@ private void mousePressed(GlobalMouseEvent event) {
/**
* Invoke mouseReleased (transition state TS_UP) for all registered listeners
*
- * @param event A global mouse event
+ * @param event a global mouse event
*/
private void mouseReleased(GlobalMouseEvent event) {
for(GlobalMouseListener listener:listeners)
@@ -164,7 +164,7 @@ private void mouseReleased(GlobalMouseEvent event) {
/**
* Invoke mouseMoved (transition state TS_MOVE) for all registered listeners
*
- * @param event A global mouse event
+ * @param event a global mouse event
*/
private void mouseMoved(GlobalMouseEvent event) {
for(GlobalMouseListener listener:listeners)
@@ -173,7 +173,7 @@ private void mouseMoved(GlobalMouseEvent event) {
/**
* Invoke mouseWheel (transition state TS_WHEEL) for all registered listeners
*
- * @param event A global mouse event
+ * @param event a global mouse event
*/
private void mouseWheel(GlobalMouseEvent event) {
for(GlobalMouseListener listener:listeners)
diff --git a/src/main/java/lc/kra/system/mouse/event/GlobalMouseAdapter.java b/src/main/java/lc/kra/system/mouse/event/GlobalMouseAdapter.java
index 490401a..721004a 100644
--- a/src/main/java/lc/kra/system/mouse/event/GlobalMouseAdapter.java
+++ b/src/main/java/lc/kra/system/mouse/event/GlobalMouseAdapter.java
@@ -23,21 +23,22 @@
public class GlobalMouseAdapter implements GlobalMouseListener {
/**
- * Invoked when a mouse button has been pressed.
+ * @see GlobalMouseListener#mousePressed(GlobalMouseEvent)
*/
@Override public void mousePressed(GlobalMouseEvent event) {}
+
/**
- * Invoked when a mouse button was released.
+ * @see GlobalMouseListener#mouseReleased(GlobalMouseEvent)
*/
@Override public void mouseReleased(GlobalMouseEvent event) {}
/**
- * Invoked when the mouse was moved.
+ * @see GlobalMouseListener#mouseMoved(GlobalMouseEvent)
*/
@Override public void mouseMoved(GlobalMouseEvent event) {}
/**
- * Invoked when a mouse wheel was scrolled.
+ * @see GlobalMouseListener#mouseWheel(GlobalMouseEvent)
*/
@Override public void mouseWheel(GlobalMouseEvent event) {}
}
\ No newline at end of file
diff --git a/src/main/java/lc/kra/system/mouse/event/GlobalMouseEvent.java b/src/main/java/lc/kra/system/mouse/event/GlobalMouseEvent.java
index 080286d..97f2772 100644
--- a/src/main/java/lc/kra/system/mouse/event/GlobalMouseEvent.java
+++ b/src/main/java/lc/kra/system/mouse/event/GlobalMouseEvent.java
@@ -69,10 +69,10 @@ public GlobalMouseEvent(Object source, int transitionState, int button, int butt
* Returns the transition state (mouse up/down, move or mouse wheel) for this mouse event.
*
* @return either one of TS_UP, TS_DOWN, TS_MOVE, TS_WHEEL.
- * @see {@link #TS_UP}
- * @see {@link #TS_DOWN}
- * @see {@link #TS_MOVE}
- * @see {@link #TS_WHEEL}
+ * @see #TS_UP
+ * @see #TS_DOWN
+ * @see #TS_MOVE
+ * @see #TS_WHEEL
*/
public int getTransitionState() { return transitionState; }
@@ -81,10 +81,10 @@ public GlobalMouseEvent(Object source, int transitionState, int button, int butt
*
* @return One of BUTTON_LEFT, BUTTON_RIGHT, BUTTON_MIDDLE or BUTTON_NO if not in transition state {@link #TS_UP} or {@link #TS_DOWN}.
* @see #getTransitionState()
- * @see {@link #BUTTON_NO}
- * @see {@link #BUTTON_LEFT}
- * @see {@link #BUTTON_RIGHT}
- * @see {@link #BUTTON_MIDDLE}
+ * @see #BUTTON_NO
+ * @see #BUTTON_LEFT
+ * @see #BUTTON_RIGHT
+ * @see #BUTTON_MIDDLE
*/
public int getButton() { return button; }
/**
@@ -92,7 +92,7 @@ public GlobalMouseEvent(Object source, int transitionState, int button, int butt
* one button is pressed the same value as for {@link #getButton()} is returned.
*
* @return The bitwise addition of {@link #BUTTON_LEFT}, {@link #BUTTON_RIGHT} and {@link #BUTTON_MIDDLE}.
- * @see {@link #getButton()}
+ * @see #getButton()
*/
public int getButtons() { return buttons; }
@@ -119,7 +119,7 @@ public GlobalMouseEvent(Object source, int transitionState, int button, int butt
public int getDelta() { return delta; }
/**
- * Returns the handle of the mouse the input was received from.
+ * @return the handle of the mouse the input was received from.
*/
public long getDeviceHandle() { return deviceHandle; }
diff --git a/src/main/java/lc/kra/system/mouse/event/GlobalMouseListener.java b/src/main/java/lc/kra/system/mouse/event/GlobalMouseListener.java
index cc75cc0..9909319 100644
--- a/src/main/java/lc/kra/system/mouse/event/GlobalMouseListener.java
+++ b/src/main/java/lc/kra/system/mouse/event/GlobalMouseListener.java
@@ -26,20 +26,29 @@
public interface GlobalMouseListener extends EventListener {
/**
* Invoked when a mouse button has been pressed.
+ *
+ * @param event a global mouse event
*/
public void mousePressed(GlobalMouseEvent event);
+
/**
* Invoked when a mouse button has been released.
+ *
+ * @param event a global mouse event
*/
public void mouseReleased(GlobalMouseEvent event);
/**
* Invoked when the mouse was moved.
+ *
+ * @param event a global mouse event
*/
public void mouseMoved(GlobalMouseEvent event);
/**
* Invoked when a mouse wheel was scrolled.
+ *
+ * @param event a global mouse event
*/
public void mouseWheel(GlobalMouseEvent event);
}
\ No newline at end of file
diff --git a/src/main/native/windows/SystemHook.c b/src/main/native/windows/SystemHook.c
index 1ef7512..7549a4f 100644
--- a/src/main/native/windows/SystemHook.c
+++ b/src/main/native/windows/SystemHook.c
@@ -216,7 +216,6 @@ LRESULT CALLBACK WndProc(HWND hWndMain, UINT uMsg, WPARAM wParam, LPARAM lParam)
UINT event = raw->data.keyboard.Message;
USHORT vkCode = raw->data.keyboard.VKey,
scanCode = raw->data.keyboard.MakeCode;
- free(lpb); // free this now to save memory
handleKey("WndProc", event, vkCode, scanCode, hDevice);
@@ -225,7 +224,6 @@ LRESULT CALLBACK WndProc(HWND hWndMain, UINT uMsg, WPARAM wParam, LPARAM lParam)
case RIM_TYPEMOUSE: {
LONG lLastX = raw->data.mouse.lLastX, lLastY = raw->data.mouse.lLastY;
USHORT buttonFlags = raw->data.mouse.usButtonFlags, buttonData = raw->data.mouse.usButtonData;
- free(lpb); // free this now to save memory
JNIEnv* env;
if((*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL)>=JNI_OK) {
@@ -267,11 +265,25 @@ LRESULT CALLBACK WndProc(HWND hWndMain, UINT uMsg, WPARAM wParam, LPARAM lParam)
break;
}
}
+
+ DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER));
+ free(lpb); // free this now to save memory
+
break;
}
- case WM_CLOSE:
+ case WM_CLOSE: {
+ // determine the hook window (by the hWndMain)
+ size_t hook = SHRT_MAX; for(size_t ridIdx=0;ridIdx