听起来你想在 OSX 上挂钩全局鼠标事件。
我已经在 Windows 中完成了它,并取得了巨大的成功。我知道要寻找什么。
这是我在快速搜索后能找到的最好的东西:
https://code.google.com/p/jnativehook/
https://code.google.com/p/jnativehook/source/browse/branches/1.1/src/native/osx/NativeThread.c
基本上,JNativeHook 执行以下操作:
它创建 ac 线程,并正确回调处理鼠标的系统函数。由于鼠标(和键盘)由系统处理,回调获取信息。然后通过回调将信息转发到代码的 java 端。
您需要创建一个线程,将其正确连接到系统,然后将信息发送到您想要记录或显示它的位置。超过 90% 的工作是在上面的 NativeThread.c 链接中完成的。这是它的一些关键部分。
第 305 到 552 行有以下内容:
switch (type) {
//...
case kCGEventLeftMouseDown:
button = kVK_LBUTTON;
SetModifierMask(kCGEventFlagMaskButtonLeft);
goto BUTTONDOWN;
case kCGEventRightMouseDown:
button = kVK_RBUTTON;
SetModifierMask(kCGEventFlagMaskButtonRight);
goto BUTTONDOWN;
case kCGEventOtherMouseDown:
button = CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber);
if (button == kVK_MBUTTON) {
SetModifierMask(kCGEventFlagMaskButtonCenter);
}
else if (button == kVK_XBUTTON1) {
SetModifierMask(kCGEventFlagMaskXButton1);
}
else if (button == kVK_XBUTTON2) {
SetModifierMask(kCGEventFlagMaskXButton2);
}
BUTTONDOWN:
#ifdef DEBUG
fprintf(stdout, "LowLevelProc(): Button Pressed (%i)\n", (unsigned int) button);
#endif
// Track the number of clicks.
#ifdef DEBUG
fprintf(stdout, "LowLevelProc(): Click Time (%lli)\n", (CGEventGetTimestamp(event) - click_time) / 1000000);
#endif
if ((long) (CGEventGetTimestamp(event) - click_time) / 1000000 <= GetMultiClickTime()) {
click_count++;
}
else {
click_count = 1;
}
click_time = CGEventGetTimestamp(event);
event_point = CGEventGetLocation(event);
jbutton = NativeToJButton(button);
jmodifiers = NativeToJEventMask(GetModifiers());
// Fire mouse pressed event.
objMouseEvent = (*env)->NewObject(
env,
clsMouseEvent,
idMouseButtonEvent,
org_jnativehook_mouse_NativeMouseEvent_NATIVE_MOUSE_PRESSED,
(jlong) event_time,
jmodifiers,
(jint) event_point.x,
(jint) event_point.y,
(jint) click_count,
jbutton);
(*env)->CallVoidMethod(env, objGlobalScreen, idDispatchEvent, objMouseEvent);
(*env)->DeleteLocalRef(env, objMouseEvent);
break;
case kCGEventLeftMouseUp:
button = kVK_LBUTTON;
UnsetModifierMask(kCGEventFlagMaskButtonLeft);
goto BUTTONUP;
case kCGEventRightMouseUp:
button = kVK_RBUTTON;
UnsetModifierMask(kCGEventFlagMaskButtonRight);
goto BUTTONUP;
case kCGEventOtherMouseUp:
button = CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber);
if (button == kVK_MBUTTON) {
UnsetModifierMask(kCGEventFlagMaskButtonCenter);
}
else if (button == kVK_XBUTTON1) {
UnsetModifierMask(kCGEventFlagMaskXButton1);
}
else if (button == kVK_XBUTTON2) {
UnsetModifierMask(kCGEventFlagMaskXButton2);
}
BUTTONUP:
#ifdef DEBUG
fprintf(stdout, "LowLevelProc(): Button Released (%i)\n", (unsigned int) button);
#endif
event_point = CGEventGetLocation(event);
jbutton = NativeToJButton(button);
jmodifiers = NativeToJEventMask(GetModifiers());
// Fire mouse released event.
objMouseEvent = (*env)->NewObject(
env,
clsMouseEvent,
idMouseButtonEvent,
org_jnativehook_mouse_NativeMouseEvent_NATIVE_MOUSE_RELEASED,
(jlong) event_time,
jmodifiers,
(jint) event_point.x,
(jint) event_point.y,
(jint) click_count,
jbutton);
(*env)->CallVoidMethod(env, objGlobalScreen, idDispatchEvent, objMouseEvent);
(*env)->DeleteLocalRef(env, objMouseEvent);
if (mouse_dragged != true) {
// Fire mouse clicked event.
objMouseEvent = (*env)->NewObject(
env,
clsMouseEvent,
idMouseButtonEvent,
org_jnativehook_mouse_NativeMouseEvent_NATIVE_MOUSE_CLICKED,
(jlong) event_time,
jmodifiers,
(jint) event_point.x,
(jint) event_point.y,
(jint) click_count,
jbutton);
(*env)->CallVoidMethod(env, objGlobalScreen, idDispatchEvent, objMouseEvent);
(*env)->DeleteLocalRef(env, objMouseEvent);
}
break;
case kCGEventLeftMouseDragged:
case kCGEventRightMouseDragged:
case kCGEventOtherMouseDragged:
event_point = CGEventGetLocation(event);
#ifdef DEBUG
fprintf(stdout, "LowLevelProc(): Motion Notified (%f, %f)\n", event_point.x, event_point.y);
#endif
// Reset the click count.
if (click_count != 0 && (long) (CGEventGetTimestamp(event) - click_time) / 1000000 > GetMultiClickTime()) {
click_count = 0;
}
jmodifiers = NativeToJEventMask(GetModifiers());
// Set the mouse dragged flag.
mouse_dragged = true;
// Fire mouse dragged event.
objMouseEvent = (*env)->NewObject(
env,
clsMouseEvent,
idMouseMotionEvent,
org_jnativehook_mouse_NativeMouseEvent_NATIVE_MOUSE_DRAGGED,
(jlong) event_time,
jmodifiers,
(jint) event_point.x,
(jint) event_point.y,
(jint) click_count);
(*env)->CallVoidMethod(env, objGlobalScreen, idDispatchEvent, objMouseEvent);
(*env)->DeleteLocalRef(env, objMouseEvent);
break;
case kCGEventMouseMoved:
event_point = CGEventGetLocation(event);
#ifdef DEBUG
fprintf(stdout, "LowLevelProc(): Motion Notified (%f, %f)\n", event_point.x, event_point.y);
#endif
// Reset the click count.
if (click_count != 0 && (long) (CGEventGetTimestamp(event) - click_time) / 1000000 > GetMultiClickTime()) {
click_count = 0;
}
jmodifiers = NativeToJEventMask(GetModifiers());
// Set the mouse dragged flag.
mouse_dragged = false;
// Fire mouse moved event.
objMouseEvent = (*env)->NewObject(
env,
clsMouseEvent,
idMouseMotionEvent,
org_jnativehook_mouse_NativeMouseEvent_NATIVE_MOUSE_MOVED,
(jlong) event_time,
jmodifiers,
(jint) event_point.x,
(jint) event_point.y,
(jint) click_count);
(*env)->CallVoidMethod(env, objGlobalScreen, idDispatchEvent, objMouseEvent);
(*env)->DeleteLocalRef(env, objMouseEvent);
break;
case kCGEventScrollWheel:
event_point = CGEventGetLocation(event);
// TODO Figure out of kCGScrollWheelEventDeltaAxis2 causes mouse events with zero rotation.
if (CGEventGetIntegerValueField(event, kCGScrollWheelEventIsContinuous) == 0) {
jscrollType = (jint) org_jnativehook_mouse_NativeMouseWheelEvent_WHEEL_UNIT_SCROLL;
}
else {
jscrollType = (jint) org_jnativehook_mouse_NativeMouseWheelEvent_WHEEL_BLOCK_SCROLL;
}
// Scrolling data uses a fixed-point 16.16 signed integer format (Ex: 1.0 = 0x00010000).
jwheelRotation = (jint) CGEventGetIntegerValueField(event, kCGScrollWheelEventDeltaAxis1) * -1;
/* TODO Figure out the scroll wheel amounts are correct. I
* suspect that Apples Java implementation maybe reporting a
* static "1" inaccurately.
*/
jscrollAmount = (jint) CGEventGetIntegerValueField(event, kCGScrollWheelEventPointDeltaAxis1) * -1;
#ifdef DEBUG
fprintf(stdout, "LowLevelProc(): Mouse Wheel Moved (%i, %i, %i)\n", (int) jscrollType, (int) jscrollAmount, (int) jwheelRotation);
#endif
// Track the number of clicks.
if ((long) (CGEventGetTimestamp(event) - click_time) / 1000000 <= GetMultiClickTime()) {
click_count++;
}
else {
click_count = 1;
}
click_time = CGEventGetTimestamp(event);
jmodifiers = NativeToJEventMask(GetModifiers());
// Fire mouse wheel event.
objMouseWheelEvent = (*env)->NewObject(
env,
clsMouseWheelEvent,
idMouseWheelEvent,
org_jnativehook_mouse_NativeMouseEvent_NATIVE_MOUSE_WHEEL,
(jlong) event_time,
jmodifiers,
(jint) event_point.x,
(jint) event_point.y,
(jint) click_count,
jscrollType,
jscrollAmount,
jwheelRotation);
(*env)->CallVoidMethod(env, objGlobalScreen, idDispatchEvent, objMouseWheelEvent);
(*env)->DeleteLocalRef(env, objMouseWheelEvent);
break;
#ifdef DEBUG
default:
fprintf(stderr, "LowLevelProc(): Unhandled Event Type: 0x%X\n", type);
break;
#endif
}
那应该让你开始。
希望有帮助。