Skip to content

Commit

Permalink
Added toggle between default, final and raw mode #37
Browse files Browse the repository at this point in the history
  • Loading branch information
kristian committed Jul 3, 2019
1 parent a744fc1 commit fc76916
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 32 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ You can include `system-hook` from this GitHub repository by adding this depende
<dependency>
<groupId>lc.kra.system</groupId>
<artifactId>system-hook</artifactId>
<version>3.4</version>
<version>3.5</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 3.4.{build}
version: 3.5.{build}

branches:
only:
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>lc.kra.system</groupId>
<artifactId>system-hook</artifactId>
<version>3.4</version>
<version>3.5</version>
<description>Global Keyboard / Mouse Hook for Java applications.</description>
<url>https://github.com/kristian/system-hook</url>

Expand Down
16 changes: 16 additions & 0 deletions src/main/java/lc/kra/system/GlobalHookMode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package lc.kra.system;

public enum GlobalHookMode {
/**
* capture events via the low-level system hook, after a event was captured any next hook registered will be called
*/
DEFAULT,
/**
* capture events via the low-level system hook, this mode will not invoke any further hooks
*/
FINAL,
/**
* capturing events in raw mode will provide you additional information of the device
*/
RAW
}
30 changes: 22 additions & 8 deletions src/main/java/lc/kra/system/keyboard/GlobalKeyboardHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,19 @@
*/
package lc.kra.system.keyboard;

import static lc.kra.system.GlobalHookMode.DEFAULT;
import static lc.kra.system.GlobalHookMode.RAW;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.TS_DOWN;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_CONTROL;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_LCONTROL;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_LMENU;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_LSHIFT;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_LWIN;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_MENU;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_RCONTROL;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_RMENU;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_RSHIFT;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_RWIN;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_LWIN;
import static lc.kra.system.keyboard.event.GlobalKeyEvent.VK_SHIFT;

import java.util.List;
Expand All @@ -40,6 +42,7 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;

import lc.kra.system.GlobalHookMode;
import lc.kra.system.LibraryLoader;
import lc.kra.system.keyboard.event.GlobalKeyEvent;
import lc.kra.system.keyboard.event.GlobalKeyListener;
Expand Down Expand Up @@ -95,11 +98,22 @@ public void run() {
* @throws UnsatisfiedLinkError Thrown if loading the native library failed
* @throws RuntimeException Thrown if registering the low-level keyboard hook failed
*/
public GlobalKeyboardHook(boolean raw) throws UnsatisfiedLinkError {
public GlobalKeyboardHook(boolean raw) throws UnsatisfiedLinkError { this(raw?RAW:DEFAULT); }

/**
* Instantiate a new GlobalKeyboardHook.
*
* @see #GlobalKeyboardHook()
*
* @param mode The mode to capture the input
* @throws UnsatisfiedLinkError Thrown if loading the native library failed
* @throws RuntimeException Thrown if registering the low-level keyboard hook failed
*/
public GlobalKeyboardHook(GlobalHookMode mode) throws UnsatisfiedLinkError {
LibraryLoader.loadLibrary(); // load the library, in case it's not already loaded

// register a keyboard hook (throws a RuntimeException in case something goes wrong)
keyboardHook = new NativeKeyboardHook(raw) {
keyboardHook = new NativeKeyboardHook(mode) {
/**
* Handle the input virtualKeyCode and transitionState, create event and add it to the inputBuffer
*/
Expand Down Expand Up @@ -178,13 +192,13 @@ public static Map<Long,String> listKeyboards() throws UnsatisfiedLinkError {

private static abstract class NativeKeyboardHook extends Thread {
private int status;
private boolean raw;
private GlobalHookMode mode;

public NativeKeyboardHook(boolean raw) {
public NativeKeyboardHook(GlobalHookMode mode) {
super("Global Keyboard Hook Thread");
setDaemon(false); setPriority(MAX_PRIORITY);
synchronized(this) {
this.raw = raw;
this.mode = mode;
try { start(); wait(); }
catch (InterruptedException e) {
throw new RuntimeException(e);
Expand All @@ -196,12 +210,12 @@ public NativeKeyboardHook(boolean raw) {
}

@Override public void run() {
status = registerHook(raw);
status = registerHook(mode.ordinal());
synchronized(this) {
notifyAll(); }
}

public native final int registerHook(boolean raw);
public native final int registerHook(int mode);
public native final void unregisterHook();

public static native final Map<Long,String> listDevices();
Expand Down
28 changes: 21 additions & 7 deletions src/main/java/lc/kra/system/mouse/GlobalMouseHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
*/
package lc.kra.system.mouse;

import static lc.kra.system.GlobalHookMode.DEFAULT;
import static lc.kra.system.GlobalHookMode.RAW;
import static lc.kra.system.mouse.event.GlobalMouseEvent.BUTTON_NO;
import static lc.kra.system.mouse.event.GlobalMouseEvent.TS_DOWN;
import static lc.kra.system.mouse.event.GlobalMouseEvent.TS_MOVE;
Expand All @@ -33,6 +35,7 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;

import lc.kra.system.GlobalHookMode;
import lc.kra.system.LibraryLoader;
import lc.kra.system.mouse.event.GlobalMouseEvent;
import lc.kra.system.mouse.event.GlobalMouseListener;
Expand Down Expand Up @@ -99,11 +102,22 @@ public void run() {
* @throws UnsatisfiedLinkError Thrown if loading the native library failed
* @throws RuntimeException Thrown if registering the low-level keyboard hook failed
*/
public GlobalMouseHook(boolean raw) throws UnsatisfiedLinkError {
public GlobalMouseHook(boolean raw) throws UnsatisfiedLinkError { this(raw?RAW:DEFAULT); }

/**
* Instantiate a new GlobalMouseHook.
*
* @see #GlobalMouseHook()
*
* @param mode The mode to capture the input
* @throws UnsatisfiedLinkError Thrown if loading the native library failed
* @throws RuntimeException Thrown if registering the low-level keyboard hook failed
*/
public GlobalMouseHook(GlobalHookMode mode) throws UnsatisfiedLinkError {
LibraryLoader.loadLibrary(); // load the library, in case it's not already loaded

// register a mouse hook (throws a RuntimeException in case something goes wrong)
mouseHook = new NativeMouseHook(raw) {
mouseHook = new NativeMouseHook(mode) {
/**
* Handle the input transitionState create event and add it to the inputBuffer
*/
Expand Down Expand Up @@ -199,13 +213,13 @@ public static Map<Long,String> listMice() throws UnsatisfiedLinkError {

private static abstract class NativeMouseHook extends Thread {
private int status;
private boolean raw;
private GlobalHookMode mode;

public NativeMouseHook(boolean raw) {
public NativeMouseHook(GlobalHookMode mode) {
super("Global Mouse Hook Thread");
setDaemon(false); setPriority(MAX_PRIORITY);
synchronized(this) {
this.raw = raw;
this.mode = mode;
try { start(); wait(); }
catch (InterruptedException e) {
throw new RuntimeException(e);
Expand All @@ -217,12 +231,12 @@ public NativeMouseHook(boolean raw) {
}

@Override public void run() {
status = registerHook(raw);
status = registerHook(mode.ordinal());
synchronized(this) {
notifyAll(); }
}

public native final int registerHook(boolean raw);
public native final int registerHook(int mode);
public native final void unregisterHook();

public static native final Map<Long,String> listDevices();
Expand Down
24 changes: 12 additions & 12 deletions src/main/native/windows/SystemHook.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ DWORD hookThreadId[2] = { 0, 0 };
BYTE keyState[256];
WCHAR buffer[4];

jint lOldX = (jint)SHRT_MIN, lOldY = (jint)SHRT_MIN;
jint lMode = 0, lOldX = (jint)SHRT_MIN, lOldY = (jint)SHRT_MIN;

BOOL APIENTRY DllMain(HINSTANCE _hInst, DWORD reason, LPVOID reserved) {
switch(reason) {
Expand Down Expand Up @@ -112,7 +112,7 @@ LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

handleKey("LowLevelKeyboardProc", wParam, pStruct->vkCode, pStruct->scanCode, 0);

return CallNextHookEx(NULL, nCode, wParam, lParam);
return nCode<0 || lMode != MODE_FINAL ? CallNextHookEx(NULL, nCode, wParam, lParam) : -1;
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if(nCode==HC_ACTION) {
Expand Down Expand Up @@ -163,7 +163,7 @@ LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
} else DEBUG_PRINT(("NATIVE: LowLevelMouseProc - Error on the attach current thread.\n"));
}

return CallNextHookEx(NULL, nCode, wParam, lParam);
return nCode<0 || lMode != MODE_FINAL ? CallNextHookEx(NULL, nCode, wParam, lParam) : -1;
}
LRESULT CALLBACK WndProc(HWND hWndMain, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg){
Expand Down Expand Up @@ -291,7 +291,7 @@ static inline _Bool notifyHookObj(JNIEnv *env, size_t hook) {
return TRUE;
}

static inline jint registerHook(JNIEnv *env, jobject thisObj, size_t hook, const char *handleName, const char *handleSig, jboolean raw) {
static inline jint registerHook(JNIEnv *env, jobject thisObj, size_t hook, const char *handleName, const char *handleSig, jint mode) {
DEBUG_PRINT(("NATIVE: registerHook - Hook start\n"));

if(jvm==NULL) (*env)->GetJavaVM(env, &jvm);
Expand All @@ -306,8 +306,8 @@ static inline jint registerHook(JNIEnv *env, jobject thisObj, size_t hook, const
}

HHOOK hHook; HWND hWnd;
switch(raw) {
case JNI_FALSE:
switch(lMode=mode) {
case MODE_DEFAULT: case MODE_FINAL:
switch(hook) {
case HOOK_KEYBOARD:
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInst, 0);
Expand All @@ -318,7 +318,7 @@ static inline jint registerHook(JNIEnv *env, jobject thisObj, size_t hook, const
}

break;
case JNI_TRUE: {
case MODE_RAW: {
WNDCLASS wndCls = {0};
wndCls.lpfnWndProc = WndProc;
wndCls.hInstance = hInst;
Expand All @@ -334,7 +334,7 @@ static inline jint registerHook(JNIEnv *env, jobject thisObj, size_t hook, const
if(hHook==NULL&&hWnd==NULL) {
debugPrintLastError("NATIVE: registerHook - Hook failed");
return (jint)E_HOOK_FAILED;
} else DEBUG_PRINT(("NATIVE: registerHook - %sHook success\n", raw?"Raw ":""));
} else DEBUG_PRINT(("NATIVE: registerHook - %sHook success\n", lMode==MODE_RAW?"Raw ":""));

if(!notifyHookObj(env, hook)) {
(*env)->ExceptionClear(env);
Expand All @@ -357,11 +357,11 @@ static inline jint registerHook(JNIEnv *env, jobject thisObj, size_t hook, const
return (jint)E_UNHOOK_FAILED;
}
}
JNIEXPORT jint JNICALL Java_lc_kra_system_keyboard_GlobalKeyboardHook_00024NativeKeyboardHook_registerHook(JNIEnv *env, jobject thisObj, jboolean raw) {
return registerHook(env, thisObj, HOOK_KEYBOARD, "handleKey", "(IICJ)V", raw);
JNIEXPORT jint JNICALL Java_lc_kra_system_keyboard_GlobalKeyboardHook_00024NativeKeyboardHook_registerHook(JNIEnv *env, jobject thisObj, jint mode) {
return registerHook(env, thisObj, HOOK_KEYBOARD, "handleKey", "(IICJ)V", mode);
}
JNIEXPORT jint JNICALL Java_lc_kra_system_mouse_GlobalMouseHook_00024NativeMouseHook_registerHook(JNIEnv *env, jobject thisObj, jboolean raw) {
return registerHook(env, thisObj, HOOK_MOUSE, "handleMouse", "(IIIIIJ)V", raw);
JNIEXPORT jint JNICALL Java_lc_kra_system_mouse_GlobalMouseHook_00024NativeMouseHook_registerHook(JNIEnv *env, jobject thisObj, jint mode) {
return registerHook(env, thisObj, HOOK_MOUSE, "handleMouse", "(IIIIIJ)V", mode);
}

static inline void unregisterHook(size_t hook) {
Expand Down
10 changes: 8 additions & 2 deletions src/main/native/windows/SystemHook.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ typedef enum {
E_NOTIFY_FAILED = -4
} GlobalHookError;

typedef enum {
MODE_DEFAULT = 0,
MODE_FINAL = 1,
MODE_RAW = 2
} GlobalHookMode;

typedef enum {
TS_UP = 0,
TS_DOWN = 1,
Expand All @@ -48,7 +54,7 @@ typedef enum {
* Method: registerHook
* Signature: (Z)I
*/
JNIEXPORT jint JNICALL Java_lc_kra_system_keyboard_GlobalKeyboardHook_00024NativeKeyboardHook_registerHook(JNIEnv *,jobject,jboolean);
JNIEXPORT jint JNICALL Java_lc_kra_system_keyboard_GlobalKeyboardHook_00024NativeKeyboardHook_registerHook(JNIEnv *,jobject,jint);
/*
* Class: GlobalKeyboardHook$NativeKeyboardHook
* Method: unregisterHook
Expand All @@ -67,7 +73,7 @@ JNIEXPORT jobject JNICALL Java_lc_kra_system_keyboard_GlobalKeyboardHook_00024Na
* Method: registerHook
* Signature: (Z)I
*/
JNIEXPORT jint JNICALL Java_lc_kra_system_mouse_GlobalMouseHook_00024NativeMouseHook_registerHook(JNIEnv *,jobject,jboolean);
JNIEXPORT jint JNICALL Java_lc_kra_system_mouse_GlobalMouseHook_00024NativeMouseHook_registerHook(JNIEnv *,jobject,jint);
/*
* Class: GlobalMouseHook$NativeMouseHook
* Method: unregisterHook
Expand Down

0 comments on commit fc76916

Please sign in to comment.