mirror of
https://github.com/shadowfacts/jinput-arm64.git
synced 2026-04-06 06:53:59 +00:00
Refactor the sources
This commit is contained in:
parent
c71f96a708
commit
682ebbaf69
46 changed files with 5 additions and 12 deletions
1
plugins/windows/src/main/native/.gitignore
vendored
Normal file
1
plugins/windows/src/main/native/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/net_java_games_input_DummyWindow.h
|
||||
103
plugins/windows/src/main/native/build.xml
Normal file
103
plugins/windows/src/main/native/build.xml
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<project name="JInput dx8 port, Native code" basedir="." default="compile">
|
||||
<property environment="env"/>
|
||||
<property name="dxhome" location="${env.DXSDK_DIR}"/>
|
||||
<property name="sdkhome" location="${env.WindowsSdkDir}"/>
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="target/natives"/>
|
||||
</target>
|
||||
|
||||
<target name="compile_dir">
|
||||
<echo message="${compiledir}"/>
|
||||
<echo message="sdkhome: ${sdkhome}"/>
|
||||
<echo message="dxhome: ${dxhome}"/>
|
||||
<echo message="target arch: ${os.arch}"/>
|
||||
<apply dir="${compiledir}" failonerror="true" executable="cl" dest="${compiledir}" skipemptyfilesets="true">
|
||||
<arg line="/Ox /W2 /nologo /c"/>
|
||||
<arg value="/I${sdkhome}\include"/>
|
||||
<arg value="/I${dxhome}\include"/>
|
||||
<arg value="/I${java.home}\..\include"/>
|
||||
<arg value="/I${java.home}\..\include\win32"/>
|
||||
<arg value="/I${commonhome}/src/native"/>
|
||||
<arg value="/I.."/>
|
||||
<srcfile/>
|
||||
<fileset dir="${compiledir}" includes="*.c"/>
|
||||
<mapper type="glob" from="*.c" to="*.obj"/>
|
||||
</apply>
|
||||
</target>
|
||||
|
||||
<!-- <target name="link" unless="nolink">-->
|
||||
<target name="link">
|
||||
<apply dir="." parallel="true" executable="cl" failonerror="true">
|
||||
<arg line="/LD /nologo"/>
|
||||
<srcfile/>
|
||||
<arg line="/Fe${dllname} /link"/>
|
||||
<arg value="/LIBPATH:${java.home}\lib"/>
|
||||
<arg value="/LIBPATH:${dxhomelib}"/>
|
||||
<arg value="/LIBPATH:${sdkhomelib}"/>
|
||||
<arg line="/DLL ${libs}"/>
|
||||
<fileset dir="${commonhome}/src/native" includes="*.obj"/>
|
||||
<fileset dir="." includes="*.obj"/>
|
||||
<fileset dir="${objdir}" includes="*.obj"/>
|
||||
</apply>
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete>
|
||||
<fileset dir="." includes="*.obj"/>
|
||||
<fileset dir="raw" includes="*.obj"/>
|
||||
<fileset dir="dx8" includes="*.obj"/>
|
||||
<fileset dir="." includes="*.dll"/>
|
||||
<fileset dir="." includes="*.exp"/>
|
||||
<fileset dir="." includes="*.lib"/>
|
||||
<fileset dir="../../../common/src/native" includes="*.obj"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target name="compile">
|
||||
<property name="rawlibs" value="Kernel32.lib User32.lib Setupapi.lib"/>
|
||||
<property name="dx8libs" value="Kernel32.lib dinput8.lib dxguid.lib User32.lib"/>
|
||||
<property name="commonhome" location="../../../common"/>
|
||||
|
||||
<condition property="dx8dllname" value="jinput-dx8.dll" else="jinput-dx8_64.dll">
|
||||
<equals arg1="${os.arch}" arg2="x86"/>
|
||||
</condition>
|
||||
<condition property="rawdllname" value="jinput-raw.dll" else="jinput-raw_64.dll">
|
||||
<equals arg1="${os.arch}" arg2="x86"/>
|
||||
</condition>
|
||||
<condition property="dxhomelib" value="${dxhome}\lib\x86" else="${dxhome}\lib\x64">
|
||||
<equals arg1="${os.arch}" arg2="x86"/>
|
||||
</condition>
|
||||
<condition property="sdkhomelib" value="${sdkhome}\lib" else="${sdkhome}\lib\x64">
|
||||
<equals arg1="${os.arch}" arg2="x86"/>
|
||||
</condition>
|
||||
<antcall target="compile_dir">
|
||||
<param name="compiledir" location="${commonhome}/src/native"/>
|
||||
</antcall>
|
||||
<antcall target="compile_dir">
|
||||
<param name="compiledir" location="."/>
|
||||
</antcall>
|
||||
<antcall target="compile_dir">
|
||||
<param name="compiledir" location="raw"/>
|
||||
</antcall>
|
||||
<antcall target="compile_dir">
|
||||
<param name="compiledir" location="dx8"/>
|
||||
</antcall>
|
||||
<!-- <uptodate property="nolink" targetfile="${dllname}">
|
||||
<srcfiles dir="." includes="*.obj"/>
|
||||
</uptodate>-->
|
||||
<antcall target="link">
|
||||
<param name="dllname" value="${dx8dllname}"/>
|
||||
<param name="libs" value="${dx8libs}"/>
|
||||
<param name="objdir" location="dx8"/>
|
||||
</antcall>
|
||||
<antcall target="link">
|
||||
<param name="dllname" value="${rawdllname}"/>
|
||||
<param name="libs" value="${rawlibs}"/>
|
||||
<param name="objdir" location="raw"/>
|
||||
</antcall>
|
||||
</target>
|
||||
</project>
|
||||
|
||||
3
plugins/windows/src/main/native/dx8/.gitignore
vendored
Normal file
3
plugins/windows/src/main/native/dx8/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/net_java_games_input_IDirectInput.h
|
||||
/net_java_games_input_IDirectInputDevice.h
|
||||
/net_java_games_input_IDirectInputEffect.h
|
||||
13
plugins/windows/src/main/native/dx8/dxversion.h
Normal file
13
plugins/windows/src/main/native/dx8/dxversion.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef DXVERSION_H
|
||||
#define DXVERSION_H
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <jni.h>
|
||||
#include "dxversion.h"
|
||||
#include <dinput.h>
|
||||
#include "net_java_games_input_IDirectInput.h"
|
||||
#include "util.h"
|
||||
#include "winutil.h"
|
||||
|
||||
typedef struct {
|
||||
LPDIRECTINPUT8 lpDirectInput;
|
||||
JNIEnv *env;
|
||||
jobject obj;
|
||||
} enum_context_t;
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_net_java_games_input_IDirectInput_createIDirectInput(JNIEnv *env, jclass unused) {
|
||||
LPDIRECTINPUT8 lpDirectInput;
|
||||
HRESULT res = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
|
||||
&IID_IDirectInput8, (void *)&lpDirectInput, NULL);
|
||||
if (FAILED(res)) {
|
||||
throwIOException(env, "Failed to create IDirectInput8 (%d)\n", res);
|
||||
return 0;
|
||||
}
|
||||
return (jlong)(INT_PTR)lpDirectInput;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK enumerateDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID context) {
|
||||
enum_context_t *enum_context = (enum_context_t *)context;
|
||||
// LPCDIDATAFORMAT lpDataFormat;
|
||||
LPDIRECTINPUTDEVICE8 lpDevice;
|
||||
DWORD device_type;
|
||||
DWORD device_subtype;
|
||||
HRESULT res;
|
||||
jclass obj_class;
|
||||
jmethodID IDirectInput_addDevice;
|
||||
jstring instance_name;
|
||||
jstring product_name;
|
||||
jbyteArray instance_guid;
|
||||
jbyteArray product_guid;
|
||||
|
||||
instance_guid = wrapGUID(enum_context->env, &(lpddi->guidInstance));
|
||||
if (instance_guid == NULL)
|
||||
return DIENUM_STOP;
|
||||
product_guid = wrapGUID(enum_context->env, &(lpddi->guidProduct));
|
||||
if (product_guid == NULL)
|
||||
return DIENUM_STOP;
|
||||
instance_name = (*enum_context->env)->NewStringUTF(enum_context->env, lpddi->tszInstanceName);
|
||||
if (instance_name == NULL)
|
||||
return DIENUM_STOP;
|
||||
product_name = (*enum_context->env)->NewStringUTF(enum_context->env, lpddi->tszProductName);
|
||||
if (product_name == NULL)
|
||||
return DIENUM_STOP;
|
||||
|
||||
obj_class = (*enum_context->env)->GetObjectClass(enum_context->env, enum_context->obj);
|
||||
if (obj_class == NULL)
|
||||
return DIENUM_STOP;
|
||||
|
||||
IDirectInput_addDevice = (*enum_context->env)->GetMethodID(enum_context->env, obj_class, "addDevice", "(J[B[BIILjava/lang/String;Ljava/lang/String;)V");
|
||||
if (IDirectInput_addDevice == NULL)
|
||||
return DIENUM_STOP;
|
||||
|
||||
res = IDirectInput8_CreateDevice(enum_context->lpDirectInput, &(lpddi->guidInstance), &lpDevice, NULL);
|
||||
if (FAILED(res)) {
|
||||
throwIOException(enum_context->env, "Failed to create device (%d)\n", res);
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
device_type = GET_DIDEVICE_TYPE(lpddi->dwDevType);
|
||||
device_subtype = GET_DIDEVICE_SUBTYPE(lpddi->dwDevType);
|
||||
|
||||
(*enum_context->env)->CallVoidMethod(enum_context->env, enum_context->obj, IDirectInput_addDevice, (jlong)(INT_PTR)lpDevice, instance_guid, product_guid, (jint)device_type, (jint)device_subtype, instance_name, product_name);
|
||||
if ((*enum_context->env)->ExceptionOccurred(enum_context->env) != NULL) {
|
||||
IDirectInputDevice8_Release(lpDevice);
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_IDirectInput_nEnumDevices(JNIEnv *env, jobject obj, jlong address) {
|
||||
LPDIRECTINPUT8 lpDirectInput = (LPDIRECTINPUT8)(INT_PTR)address;
|
||||
HRESULT res;
|
||||
|
||||
enum_context_t enum_context;
|
||||
enum_context.lpDirectInput = lpDirectInput;
|
||||
enum_context.env = env;
|
||||
enum_context.obj = obj;
|
||||
res = IDirectInput8_EnumDevices(lpDirectInput, DI8DEVCLASS_ALL, enumerateDevicesCallback, &enum_context, DIEDFL_ATTACHEDONLY);
|
||||
if (FAILED(res)) {
|
||||
throwIOException(env, "Failed to enumerate devices (%d)\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_IDirectInput_nRelease(JNIEnv *env, jclass unused, jlong address) {
|
||||
LPDIRECTINPUT8 lpDirectInput = (LPDIRECTINPUT8)(INT_PTR)address;
|
||||
IDirectInput8_Release(lpDirectInput);
|
||||
}
|
||||
|
|
@ -0,0 +1,502 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "dxversion.h"
|
||||
#include <jni.h>
|
||||
#include <dinput.h>
|
||||
#include "net_java_games_input_IDirectInputDevice.h"
|
||||
#include "util.h"
|
||||
#include "winutil.h"
|
||||
|
||||
typedef struct {
|
||||
JNIEnv *env;
|
||||
jobject device_obj;
|
||||
} enum_context_t;
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nSetBufferSize(JNIEnv *env, jclass unused, jlong address, jint size) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
DIPROPDWORD dipropdw;
|
||||
HRESULT res;
|
||||
|
||||
dipropdw.diph.dwSize = sizeof(DIPROPDWORD);
|
||||
dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
dipropdw.diph.dwObj = 0;
|
||||
dipropdw.diph.dwHow = DIPH_DEVICE;
|
||||
dipropdw.dwData = size;
|
||||
res = IDirectInputDevice8_SetProperty(lpDevice, DIPROP_BUFFERSIZE, &dipropdw.diph);
|
||||
return res;
|
||||
}
|
||||
|
||||
static jint mapGUIDType(const GUID *guid) {
|
||||
if (IsEqualGUID(guid, &GUID_XAxis)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_XAxis;
|
||||
} else if (IsEqualGUID(guid, &GUID_YAxis)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_YAxis;
|
||||
} else if (IsEqualGUID(guid, &GUID_ZAxis)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_ZAxis;
|
||||
} else if (IsEqualGUID(guid, &GUID_RxAxis)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_RxAxis;
|
||||
} else if (IsEqualGUID(guid, &GUID_RyAxis)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_RyAxis;
|
||||
} else if (IsEqualGUID(guid, &GUID_RzAxis)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_RzAxis;
|
||||
} else if (IsEqualGUID(guid, &GUID_Slider)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Slider;
|
||||
} else if (IsEqualGUID(guid, &GUID_Button)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Button;
|
||||
} else if (IsEqualGUID(guid, &GUID_Key)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Key;
|
||||
} else if (IsEqualGUID(guid, &GUID_POV)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_POV;
|
||||
} else if (IsEqualGUID(guid, &GUID_ConstantForce)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_ConstantForce;
|
||||
} else if (IsEqualGUID(guid, &GUID_RampForce)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_RampForce;
|
||||
} else if (IsEqualGUID(guid, &GUID_Square)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Square;
|
||||
} else if (IsEqualGUID(guid, &GUID_Sine)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Sine;
|
||||
} else if (IsEqualGUID(guid, &GUID_Triangle)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Triangle;
|
||||
} else if (IsEqualGUID(guid, &GUID_SawtoothUp)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_SawtoothUp;
|
||||
} else if (IsEqualGUID(guid, &GUID_SawtoothDown)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_SawtoothDown;
|
||||
} else if (IsEqualGUID(guid, &GUID_Spring)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Spring;
|
||||
} else if (IsEqualGUID(guid, &GUID_Damper)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Damper;
|
||||
} else if (IsEqualGUID(guid, &GUID_Inertia)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Inertia;
|
||||
} else if (IsEqualGUID(guid, &GUID_Friction)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Friction;
|
||||
} else if (IsEqualGUID(guid, &GUID_CustomForce)) {
|
||||
return net_java_games_input_IDirectInputDevice_GUID_CustomForce;
|
||||
} else
|
||||
return net_java_games_input_IDirectInputDevice_GUID_Unknown;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK enumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef) {
|
||||
enum_context_t *enum_context = (enum_context_t *)pvRef;
|
||||
jmethodID add_method;
|
||||
jstring name;
|
||||
jbyteArray guid;
|
||||
JNIEnv *env = enum_context->env;
|
||||
jobject device_obj = enum_context->device_obj;
|
||||
jint guid_id;
|
||||
jclass obj_class = (*env)->GetObjectClass(env, device_obj);
|
||||
|
||||
|
||||
if (obj_class == NULL)
|
||||
return DIENUM_STOP;
|
||||
guid = wrapGUID(env, &(pdei->guid));
|
||||
if (guid == NULL)
|
||||
return DIENUM_STOP;
|
||||
add_method = (*env)->GetMethodID(env, obj_class, "addEffect", "([BIIIILjava/lang/String;)V");
|
||||
if (add_method == NULL)
|
||||
return DIENUM_STOP;
|
||||
name = (*env)->NewStringUTF(env, pdei->tszName);
|
||||
if (name == NULL)
|
||||
return DIENUM_STOP;
|
||||
guid_id = mapGUIDType(&(pdei->guid));
|
||||
(*env)->CallBooleanMethod(env, device_obj, add_method, guid, guid_id, (jint)pdei->dwEffType, (jint)pdei->dwStaticParams, (jint)pdei->dwDynamicParams, name);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK enumObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) {
|
||||
enum_context_t *enum_context = (enum_context_t *)pvRef;
|
||||
jmethodID add_method;
|
||||
jstring name;
|
||||
DWORD instance;
|
||||
DWORD type;
|
||||
jint guid_type;
|
||||
jbyteArray guid;
|
||||
JNIEnv *env = enum_context->env;
|
||||
jobject device_obj = enum_context->device_obj;
|
||||
jclass obj_class = (*env)->GetObjectClass(env, device_obj);
|
||||
|
||||
if (obj_class == NULL)
|
||||
return DIENUM_STOP;
|
||||
guid = wrapGUID(env, &(lpddoi->guidType));
|
||||
if (guid == NULL)
|
||||
return DIENUM_STOP;
|
||||
add_method = (*env)->GetMethodID(env, obj_class, "addObject", "([BIIIIILjava/lang/String;)V");
|
||||
if (add_method == NULL)
|
||||
return DIENUM_STOP;
|
||||
name = (*env)->NewStringUTF(env, lpddoi->tszName);
|
||||
if (name == NULL)
|
||||
return DIENUM_STOP;
|
||||
instance = DIDFT_GETINSTANCE(lpddoi->dwType);
|
||||
type = DIDFT_GETTYPE(lpddoi->dwType);
|
||||
guid_type = mapGUIDType(&(lpddoi->guidType));
|
||||
//printfJava(env, "name %s guid_type %d id %d\n", lpddoi->tszName, guid_type, lpddoi->dwType);
|
||||
(*env)->CallBooleanMethod(env, device_obj, add_method, guid, (jint)guid_type, (jint)lpddoi->dwType, (jint)type, (jint)instance, (jint)lpddoi->dwFlags, name);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetRangeProperty(JNIEnv *env, jclass unused, jlong address, jint object_id, jlongArray range_array_obj) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
DIPROPRANGE range;
|
||||
HRESULT res;
|
||||
jlong range_array[2];
|
||||
|
||||
range.diph.dwSize = sizeof(DIPROPRANGE);
|
||||
range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
range.diph.dwObj = object_id;
|
||||
range.diph.dwHow = DIPH_BYID;
|
||||
res = IDirectInputDevice8_GetProperty(lpDevice, DIPROP_RANGE, &(range.diph));
|
||||
range_array[0] = range.lMin;
|
||||
range_array[1] = range.lMax;
|
||||
(*env)->SetLongArrayRegion(env, range_array_obj, 0, 2, range_array);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetDeadzoneProperty(JNIEnv *env, jclass unused, jlong address, jint object_id) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
DIPROPDWORD deadzone;
|
||||
HRESULT res;
|
||||
|
||||
deadzone.diph.dwSize = sizeof(deadzone);
|
||||
deadzone.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
deadzone.diph.dwObj = object_id;
|
||||
deadzone.diph.dwHow = DIPH_BYID;
|
||||
res = IDirectInputDevice8_GetProperty(lpDevice, DIPROP_DEADZONE, &(deadzone.diph));
|
||||
if (res != DI_OK && res != S_FALSE)
|
||||
throwIOException(env, "Failed to get deadzone property (%x)\n", res);
|
||||
return deadzone.dwData;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nSetDataFormat(JNIEnv *env, jclass unused, jlong address, jint flags, jobjectArray objects) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
DIDATAFORMAT data_format;
|
||||
jsize num_objects = (*env)->GetArrayLength(env, objects);
|
||||
/*
|
||||
* Data size must be a multiple of 4, but since sizeof(jint) is
|
||||
* 4, we're safe
|
||||
*/
|
||||
DWORD data_size = num_objects*sizeof(jint);
|
||||
GUID *guids;
|
||||
DIOBJECTDATAFORMAT *object_formats;
|
||||
int i;
|
||||
HRESULT res;
|
||||
jclass clazz;
|
||||
jmethodID getGUID_method;
|
||||
jmethodID getFlags_method;
|
||||
jmethodID getType_method;
|
||||
jmethodID getInstance_method;
|
||||
jobject object;
|
||||
jint type;
|
||||
jint object_flags;
|
||||
jint instance;
|
||||
jobject guid_array;
|
||||
DWORD composite_type;
|
||||
DWORD flags_masked;
|
||||
LPDIOBJECTDATAFORMAT object_format;
|
||||
|
||||
data_format.dwSize = sizeof(DIDATAFORMAT);
|
||||
data_format.dwObjSize = sizeof(DIOBJECTDATAFORMAT);
|
||||
data_format.dwFlags = flags;
|
||||
data_format.dwDataSize = data_size;
|
||||
data_format.dwNumObjs = num_objects;
|
||||
|
||||
clazz = (*env)->FindClass(env, "net/java/games/input/DIDeviceObject");
|
||||
if (clazz == NULL)
|
||||
return -1;
|
||||
getGUID_method = (*env)->GetMethodID(env, clazz, "getGUID", "()[B");
|
||||
if (getGUID_method == NULL)
|
||||
return -1;
|
||||
getFlags_method = (*env)->GetMethodID(env, clazz, "getFlags", "()I");
|
||||
if (getFlags_method == NULL)
|
||||
return -1;
|
||||
getType_method = (*env)->GetMethodID(env, clazz, "getType", "()I");
|
||||
if (getType_method == NULL)
|
||||
return -1;
|
||||
getInstance_method = (*env)->GetMethodID(env, clazz, "getInstance", "()I");
|
||||
if (getInstance_method == NULL)
|
||||
return -1;
|
||||
|
||||
guids = (GUID *)malloc(num_objects*sizeof(GUID));
|
||||
if (guids == NULL) {
|
||||
throwIOException(env, "Failed to allocate GUIDs");
|
||||
return -1;
|
||||
}
|
||||
object_formats = (DIOBJECTDATAFORMAT *)malloc(num_objects*sizeof(DIOBJECTDATAFORMAT));
|
||||
if (object_formats == NULL) {
|
||||
free(guids);
|
||||
throwIOException(env, "Failed to allocate data format");
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < num_objects; i++) {
|
||||
object = (*env)->GetObjectArrayElement(env, objects, i);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(guids);
|
||||
free(object_formats);
|
||||
return -1;
|
||||
}
|
||||
guid_array = (*env)->CallObjectMethod(env, object, getGUID_method);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(guids);
|
||||
free(object_formats);
|
||||
return -1;
|
||||
}
|
||||
unwrapGUID(env, guid_array, guids + i);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(guids);
|
||||
free(object_formats);
|
||||
return -1;
|
||||
}
|
||||
type = (*env)->CallIntMethod(env, object, getType_method);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(guids);
|
||||
free(object_formats);
|
||||
return -1;
|
||||
}
|
||||
object_flags = (*env)->CallIntMethod(env, object, getFlags_method);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(guids);
|
||||
free(object_formats);
|
||||
return -1;
|
||||
}
|
||||
instance = (*env)->CallIntMethod(env, object, getInstance_method);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(guids);
|
||||
free(object_formats);
|
||||
return -1;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, object);
|
||||
composite_type = type | DIDFT_MAKEINSTANCE(instance);
|
||||
flags_masked = flags & (DIDOI_ASPECTACCEL | DIDOI_ASPECTFORCE | DIDOI_ASPECTPOSITION | DIDOI_ASPECTVELOCITY);
|
||||
object_format = object_formats + i;
|
||||
object_format->pguid = guids + i;
|
||||
object_format->dwType = composite_type;
|
||||
object_format->dwFlags = flags_masked;
|
||||
// dwOfs must be multiple of 4, but sizeof(jint) is 4, so we're safe
|
||||
object_format->dwOfs = i*sizeof(jint);
|
||||
}
|
||||
data_format.rgodf = object_formats;
|
||||
res = IDirectInputDevice8_SetDataFormat(lpDevice, &data_format);
|
||||
free(guids);
|
||||
free(object_formats);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nAcquire(JNIEnv *env, jclass unused, jlong address) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
|
||||
HRESULT res = IDirectInputDevice8_Acquire(lpDevice);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nUnacquire(JNIEnv *env, jclass unused, jlong address) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
|
||||
HRESULT res = IDirectInputDevice8_Unacquire(lpDevice);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nPoll(JNIEnv *env, jclass unused, jlong address) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
|
||||
HRESULT res = IDirectInputDevice8_Poll(lpDevice);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetDeviceState(JNIEnv *env, jclass unused, jlong address, jintArray device_state_array) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
jsize state_length = (*env)->GetArrayLength(env, device_state_array);
|
||||
DWORD state_size = state_length*sizeof(jint);
|
||||
HRESULT res;
|
||||
jint *device_state = (*env)->GetIntArrayElements(env, device_state_array, NULL);
|
||||
if (device_state == NULL)
|
||||
return -1;
|
||||
|
||||
res = IDirectInputDevice8_GetDeviceState(lpDevice, state_size, device_state);
|
||||
(*env)->ReleaseIntArrayElements(env, device_state_array, device_state, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetDeviceData(JNIEnv *env, jclass unused, jlong address, jint flags, jobject queue, jobject queue_array, jint position, jint remaining) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
DWORD num_events = remaining;
|
||||
DIDEVICEOBJECTDATA *data;
|
||||
DIDEVICEOBJECTDATA *data_element;
|
||||
jmethodID set_method;
|
||||
HRESULT res;
|
||||
int i;
|
||||
jclass data_class;
|
||||
jclass queue_class;
|
||||
jmethodID position_method;
|
||||
|
||||
data_class = (*env)->FindClass(env, "net/java/games/input/DIDeviceObjectData");
|
||||
if (data_class == NULL)
|
||||
return -1;
|
||||
set_method = (*env)->GetMethodID(env, data_class, "set", "(IIII)V");
|
||||
if (set_method == NULL)
|
||||
return -1;
|
||||
queue_class = (*env)->GetObjectClass(env, queue);
|
||||
if (queue_class == NULL)
|
||||
return -1;
|
||||
position_method = (*env)->GetMethodID(env, queue_class, "position", "(I)V");
|
||||
if (position_method == NULL)
|
||||
return -1;
|
||||
|
||||
data = (DIDEVICEOBJECTDATA *)malloc(num_events*sizeof(DIDEVICEOBJECTDATA));
|
||||
if (data == NULL)
|
||||
return -1;
|
||||
|
||||
res = IDirectInputDevice8_GetDeviceData(lpDevice, sizeof(DIDEVICEOBJECTDATA), data, &num_events, flags);
|
||||
if (res == DI_OK || res == DI_BUFFEROVERFLOW) {
|
||||
for (i = 0; i < num_events; i++) {
|
||||
jobject queue_element = (*env)->GetObjectArrayElement(env, queue_array, position + i);
|
||||
if (queue_element == NULL) {
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
data_element = data + i;
|
||||
(*env)->CallVoidMethod(env, queue_element, set_method, (jint)data_element->dwOfs, (jint)data_element->dwData, (jint)data_element->dwTimeStamp, (jint)data_element->dwSequence);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
(*env)->CallVoidMethod(env, queue, position_method, position + num_events);
|
||||
}
|
||||
free(data);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nEnumEffects(JNIEnv *env, jobject device_obj, jlong address, jint flags) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
HRESULT res;
|
||||
enum_context_t enum_context;
|
||||
|
||||
enum_context.env = env;
|
||||
enum_context.device_obj = device_obj;
|
||||
res = IDirectInputDevice8_EnumEffects(lpDevice, enumEffectsCallback, &enum_context, flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nEnumObjects(JNIEnv *env, jobject device_obj, jlong address, jint flags) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
HRESULT res;
|
||||
enum_context_t enum_context;
|
||||
|
||||
enum_context.env = env;
|
||||
enum_context.device_obj = device_obj;
|
||||
res = IDirectInputDevice8_EnumObjects(lpDevice, enumObjectsCallback, &enum_context, flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nSetCooperativeLevel(JNIEnv *env, jclass unused, jlong address, jlong hwnd_address, jint flags) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
HWND hwnd = (HWND)(INT_PTR)hwnd_address;
|
||||
|
||||
HRESULT res = IDirectInputDevice8_SetCooperativeLevel(lpDevice, hwnd, flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_IDirectInputDevice_nRelease(JNIEnv *env, jclass unused, jlong address) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
|
||||
IDirectInputDevice8_Release(lpDevice);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_net_java_games_input_IDirectInputDevice_nCreatePeriodicEffect(JNIEnv *env, jclass unused, jlong address, jbyteArray effect_guid_array, jint flags, jint duration, jint sample_period, jint gain, jint trigger_button, jint trigger_repeat_interval, jintArray axis_ids_array, jlongArray directions_array, jint envelope_attack_level, jint envelope_attack_time, jint envelope_fade_level, jint envelope_fade_time, jint periodic_magnitude, jint periodic_offset, jint periodic_phase, jint periodic_period, jint start_delay) {
|
||||
LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
|
||||
LPDIRECTINPUTEFFECT lpdiEffect;
|
||||
DIEFFECT effect;
|
||||
GUID effect_guid;
|
||||
jint *axis_ids;
|
||||
jlong *directions;
|
||||
jsize num_axes;
|
||||
jsize num_directions;
|
||||
LONG *directions_long;
|
||||
DWORD *axis_ids_dword;
|
||||
HRESULT res;
|
||||
DIPERIODIC periodic;
|
||||
DIENVELOPE envelope;
|
||||
int i;
|
||||
|
||||
num_axes = (*env)->GetArrayLength(env, axis_ids_array);
|
||||
num_directions = (*env)->GetArrayLength(env, directions_array);
|
||||
|
||||
if (num_axes != num_directions) {
|
||||
throwIOException(env, "axis_ids.length != directions.length\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unwrapGUID(env, effect_guid_array, &effect_guid);
|
||||
if ((*env)->ExceptionOccurred(env))
|
||||
return 0;
|
||||
axis_ids = (*env)->GetIntArrayElements(env, axis_ids_array, NULL);
|
||||
if (axis_ids == NULL)
|
||||
return 0;
|
||||
directions = (*env)->GetLongArrayElements(env, directions_array, NULL);
|
||||
if (axis_ids == NULL)
|
||||
return 0;
|
||||
axis_ids_dword = (DWORD *)malloc(sizeof(DWORD)*num_axes);
|
||||
if (axis_ids_dword == NULL) {
|
||||
throwIOException(env, "Failed to allocate axes array\n");
|
||||
return 0;
|
||||
}
|
||||
directions_long = (LONG *)malloc(sizeof(LONG)*num_directions);
|
||||
if (directions_long == NULL) {
|
||||
free(axis_ids_dword);
|
||||
throwIOException(env, "Failed to allocate directions array\n");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < num_axes; i++) {
|
||||
axis_ids_dword[i] = axis_ids[i];
|
||||
}
|
||||
for (i = 0; i < num_directions; i++) {
|
||||
directions_long[i] = directions[i];
|
||||
}
|
||||
|
||||
envelope.dwSize = sizeof(DIENVELOPE);
|
||||
envelope.dwAttackLevel = envelope_attack_level;
|
||||
envelope.dwAttackTime = envelope_attack_time;
|
||||
envelope.dwFadeLevel = envelope_fade_level;
|
||||
envelope.dwFadeTime = envelope_fade_time;
|
||||
|
||||
periodic.dwMagnitude = periodic_magnitude;
|
||||
periodic.lOffset = periodic_offset;
|
||||
periodic.dwPhase = periodic_phase;
|
||||
periodic.dwPeriod = periodic_period;
|
||||
|
||||
effect.dwSize = sizeof(DIEFFECT);
|
||||
effect.dwFlags = flags;
|
||||
effect.dwDuration = duration;
|
||||
effect.dwSamplePeriod = sample_period;
|
||||
effect.dwGain = gain;
|
||||
effect.dwTriggerButton = trigger_button;
|
||||
effect.dwTriggerRepeatInterval = trigger_repeat_interval;
|
||||
effect.cAxes = num_axes;
|
||||
effect.rgdwAxes = axis_ids_dword;
|
||||
effect.rglDirection = directions_long;
|
||||
effect.lpEnvelope = &envelope;
|
||||
effect.cbTypeSpecificParams = sizeof(periodic);
|
||||
effect.lpvTypeSpecificParams = &periodic;
|
||||
effect.dwStartDelay = start_delay;
|
||||
|
||||
res = IDirectInputDevice8_CreateEffect(lpDevice, &effect_guid, &effect, &lpdiEffect, NULL);
|
||||
(*env)->ReleaseIntArrayElements(env, axis_ids_array, axis_ids, 0);
|
||||
(*env)->ReleaseLongArrayElements(env, directions_array, directions, 0);
|
||||
free(axis_ids_dword);
|
||||
free(directions_long);
|
||||
if (res != DI_OK) {
|
||||
throwIOException(env, "Failed to create effect (0x%x)\n", res);
|
||||
return 0;
|
||||
}
|
||||
return (jlong)(INT_PTR)lpdiEffect;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "dxversion.h"
|
||||
#include <jni.h>
|
||||
#include <dinput.h>
|
||||
#include "net_java_games_input_IDirectInputEffect.h"
|
||||
#include "util.h"
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_IDirectInputEffect_nRelease(JNIEnv *env, jclass unused, jlong address) {
|
||||
LPDIRECTINPUTEFFECT ppdeff = (LPDIRECTINPUTEFFECT)(INT_PTR)address;
|
||||
|
||||
IDirectInputEffect_Release(ppdeff);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputEffect_nSetGain(JNIEnv *env, jclass unused, jlong address, jint gain) {
|
||||
LPDIRECTINPUTEFFECT ppdeff = (LPDIRECTINPUTEFFECT)(INT_PTR)address;
|
||||
DIEFFECT params;
|
||||
|
||||
ZeroMemory(¶ms, sizeof(params));
|
||||
params.dwSize = sizeof(params);
|
||||
params.dwGain = gain;
|
||||
|
||||
return IDirectInputEffect_SetParameters(ppdeff, ¶ms, DIEP_GAIN);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputEffect_nStart(JNIEnv *env, jclass unused, jlong address, jint iterations, jint flags) {
|
||||
LPDIRECTINPUTEFFECT ppdeff = (LPDIRECTINPUTEFFECT)(INT_PTR)address;
|
||||
|
||||
return IDirectInputEffect_Start(ppdeff, iterations, flags);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputEffect_nStop(JNIEnv *env, jclass unused, jlong address) {
|
||||
LPDIRECTINPUTEFFECT ppdeff = (LPDIRECTINPUTEFFECT)(INT_PTR)address;
|
||||
|
||||
return IDirectInputEffect_Stop(ppdeff);
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <jni.h>
|
||||
#include "net_java_games_input_DummyWindow.h"
|
||||
#include "util.h"
|
||||
|
||||
static const TCHAR* DUMMY_WINDOW_NAME = "JInputControllerWindow";
|
||||
|
||||
static LRESULT CALLBACK DummyWndProc(
|
||||
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
static BOOL RegisterDummyWindow(HINSTANCE hInstance)
|
||||
{
|
||||
WNDCLASSEX wcex;
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = (WNDPROC)DummyWndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = NULL;
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||
wcex.lpszMenuName = (LPCSTR)NULL;
|
||||
wcex.lpszClassName = DUMMY_WINDOW_NAME;
|
||||
wcex.hIconSm = NULL;
|
||||
return RegisterClassEx(&wcex);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_net_java_games_input_DummyWindow_createWindow(JNIEnv *env, jclass unused) {
|
||||
HINSTANCE hInst = GetModuleHandle(NULL);
|
||||
HWND hwndDummy;
|
||||
WNDCLASSEX class_info;
|
||||
class_info.cbSize = sizeof(WNDCLASSEX);
|
||||
class_info.cbClsExtra = 0;
|
||||
class_info.cbWndExtra = 0;
|
||||
|
||||
if (!GetClassInfoEx(hInst, DUMMY_WINDOW_NAME, &class_info)) {
|
||||
// Register the dummy input window
|
||||
if (!RegisterDummyWindow(hInst)) {
|
||||
throwIOException(env, "Failed to register window class (%d)\n", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the dummy input window
|
||||
hwndDummy = CreateWindow(DUMMY_WINDOW_NAME, NULL,
|
||||
WS_POPUP | WS_ICONIC,
|
||||
0, 0, 0, 0, NULL, NULL, hInst, NULL);
|
||||
if (hwndDummy == NULL) {
|
||||
throwIOException(env, "Failed to create window (%d)\n", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
return (jlong)(intptr_t)hwndDummy;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_DummyWindow_nDestroy(JNIEnv *env, jclass unused, jlong hwnd_address) {
|
||||
HWND hwndDummy = (HWND)(INT_PTR)hwnd_address;
|
||||
BOOL result = DestroyWindow(hwndDummy);
|
||||
if (!result) {
|
||||
throwIOException(env, "Failed to destroy window (%d)\n", GetLastError());
|
||||
}
|
||||
}
|
||||
4
plugins/windows/src/main/native/raw/.gitignore
vendored
Normal file
4
plugins/windows/src/main/native/raw/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/net_java_games_input_RawDevice.h
|
||||
/net_java_games_input_RawInputEnvironmentPlugin.h
|
||||
/net_java_games_input_RawInputEventQueue_QueueThread.h
|
||||
/net_java_games_input_RawInputEventQueue.h
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include "rawwinver.h"
|
||||
#include <windows.h>
|
||||
#include <winuser.h>
|
||||
#include <jni.h>
|
||||
#include "net_java_games_input_RawDevice.h"
|
||||
#include "util.h"
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_net_java_games_input_RawDevice_nGetName(JNIEnv *env, jclass unused, jlong handle_addr) {
|
||||
HANDLE handle = (HANDLE)(INT_PTR)handle_addr;
|
||||
UINT res;
|
||||
UINT name_length;
|
||||
char *name;
|
||||
jstring name_str;
|
||||
|
||||
res = GetRawInputDeviceInfo(handle, RIDI_DEVICENAME, NULL, &name_length);
|
||||
name = (char *)malloc(name_length*sizeof(char));
|
||||
res = GetRawInputDeviceInfo(handle, RIDI_DEVICENAME, name, &name_length);
|
||||
if ((UINT)-1 == res) {
|
||||
free(name);
|
||||
throwIOException(env, "Failed to get device name (%d)\n", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
name_str = (*env)->NewStringUTF(env, name);
|
||||
free(name);
|
||||
return name_str;
|
||||
}
|
||||
|
||||
static jobject createKeyboardInfo(JNIEnv *env, jobject device_obj, RID_DEVICE_INFO_KEYBOARD *device_info) {
|
||||
return newJObject(env, "net/java/games/input/RawKeyboardInfo", "(Lnet/java/games/input/RawDevice;IIIIII)V", device_obj, (jint)device_info->dwType, (jint)device_info->dwSubType, (jint)device_info->dwKeyboardMode, (jint)device_info->dwNumberOfFunctionKeys, (jint)device_info->dwNumberOfIndicators, (jint)device_info->dwNumberOfKeysTotal);
|
||||
}
|
||||
|
||||
static jobject createMouseInfo(JNIEnv *env, jobject device_obj, RID_DEVICE_INFO_MOUSE *device_info) {
|
||||
return newJObject(env, "net/java/games/input/RawMouseInfo", "(Lnet/java/games/input/RawDevice;III)V", device_obj, (jint)device_info->dwId, (jint)device_info->dwNumberOfButtons, (jint)device_info->dwSampleRate);
|
||||
}
|
||||
|
||||
static jobject createHIDInfo(JNIEnv *env, jobject device_obj, RID_DEVICE_INFO_HID *device_info) {
|
||||
return newJObject(env, "net/java/games/input/RawHIDInfo", "(Lnet/java/games/input/RawDevice;IIIII)V", device_obj, (jint)device_info->dwVendorId, (jint)device_info->dwProductId, (jint)device_info->dwVersionNumber, (jint)device_info->usUsagePage, (jint)device_info->usUsage);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_net_java_games_input_RawDevice_nGetInfo(JNIEnv *env, jclass unused, jobject device_obj, jlong handle_addr) {
|
||||
HANDLE handle = (HANDLE)(INT_PTR)handle_addr;
|
||||
RID_DEVICE_INFO device_info;
|
||||
UINT size = sizeof(RID_DEVICE_INFO);
|
||||
UINT res;
|
||||
|
||||
device_info.cbSize = sizeof(RID_DEVICE_INFO);
|
||||
res = GetRawInputDeviceInfo(handle, RIDI_DEVICEINFO, &device_info, &size);
|
||||
if ((UINT)-1 == res) {
|
||||
throwIOException(env, "Failed to get device info (%d)\n", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
switch (device_info.dwType) {
|
||||
case RIM_TYPEHID:
|
||||
return createHIDInfo(env, device_obj,&(device_info.hid));
|
||||
case RIM_TYPEKEYBOARD:
|
||||
return createKeyboardInfo(env, device_obj, &(device_info.keyboard));
|
||||
case RIM_TYPEMOUSE:
|
||||
return createMouseInfo(env, device_obj, &(device_info.mouse));
|
||||
default:
|
||||
throwIOException(env, "Unknown device type: %d\n", device_info.dwType);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include "rawwinver.h"
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include <devguid.h>
|
||||
#include <regstr.h>
|
||||
#include <jni.h>
|
||||
#include "net_java_games_input_RawInputEnvironmentPlugin.h"
|
||||
#include "util.h"
|
||||
#include "winutil.h"
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_net_java_games_input_RawInputEnvironmentPlugin_getKeyboardClassGUID(JNIEnv *env, jclass unused) {
|
||||
return wrapGUID(env, &GUID_DEVCLASS_KEYBOARD);
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_net_java_games_input_RawInputEnvironmentPlugin_getMouseClassGUID(JNIEnv *env, jclass unused) {
|
||||
return wrapGUID(env, &GUID_DEVCLASS_MOUSE);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_RawInputEnvironmentPlugin_nEnumSetupAPIDevices(JNIEnv *env, jclass unused, jbyteArray guid_array, jobject device_list) {
|
||||
jclass list_class;
|
||||
jmethodID add_method;
|
||||
HDEVINFO hDevInfo;
|
||||
SP_DEVINFO_DATA DeviceInfoData;
|
||||
int i;
|
||||
GUID setup_class_guid;
|
||||
jstring device_name;
|
||||
jstring device_instance_id;
|
||||
jobject setup_api_device;
|
||||
|
||||
list_class = (*env)->GetObjectClass(env, device_list);
|
||||
if (list_class == NULL)
|
||||
return;
|
||||
add_method = (*env)->GetMethodID(env, list_class, "add", "(Ljava/lang/Object;)Z");
|
||||
if (add_method == NULL)
|
||||
return;
|
||||
unwrapGUID(env, guid_array, &setup_class_guid);
|
||||
if ((*env)->ExceptionOccurred(env))
|
||||
return;
|
||||
|
||||
hDevInfo = SetupDiGetClassDevs(&setup_class_guid,
|
||||
NULL,
|
||||
NULL,
|
||||
DIGCF_PRESENT);
|
||||
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE) {
|
||||
throwIOException(env, "Failed to create device enumerator (%d)\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) {
|
||||
DWORD DataT;
|
||||
LPTSTR buffer = NULL;
|
||||
DWORD buffersize = 0;
|
||||
|
||||
|
||||
while (!SetupDiGetDeviceRegistryProperty(
|
||||
hDevInfo,
|
||||
&DeviceInfoData,
|
||||
SPDRP_DEVICEDESC,
|
||||
&DataT,
|
||||
(PBYTE)buffer,
|
||||
buffersize,
|
||||
&buffersize)) {
|
||||
if (buffer != NULL)
|
||||
free(buffer);
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
buffer = malloc(buffersize);
|
||||
} else {
|
||||
throwIOException(env, "Failed to get device description (%x)\n", GetLastError());
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
device_name = (*env)->NewStringUTF(env, buffer);
|
||||
if (device_name == NULL) {
|
||||
free(buffer);
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
while (!SetupDiGetDeviceInstanceId(
|
||||
hDevInfo,
|
||||
&DeviceInfoData,
|
||||
buffer,
|
||||
buffersize,
|
||||
&buffersize))
|
||||
{
|
||||
if (buffer != NULL)
|
||||
free(buffer);
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
buffer = malloc(buffersize);
|
||||
} else {
|
||||
throwIOException(env, "Failed to get device instance id (%x)\n", GetLastError());
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
device_instance_id = (*env)->NewStringUTF(env, buffer);
|
||||
if (buffer != NULL)
|
||||
free(buffer);
|
||||
if (device_instance_id == NULL) {
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return;
|
||||
}
|
||||
setup_api_device = newJObject(env, "net/java/games/input/SetupAPIDevice", "(Ljava/lang/String;Ljava/lang/String;)V", device_instance_id, device_name);
|
||||
if (setup_api_device == NULL) {
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return;
|
||||
}
|
||||
(*env)->CallBooleanMethod(env, device_list, add_method, setup_api_device);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_RawInputEnvironmentPlugin_enumerateDevices(JNIEnv *env, jclass unused, jobject queue, jobject device_list) {
|
||||
UINT num_devices;
|
||||
UINT res;
|
||||
RAWINPUTDEVICELIST *devices;
|
||||
RAWINPUTDEVICELIST *device;
|
||||
jobject device_object;
|
||||
jclass list_class;
|
||||
jmethodID add_method;
|
||||
int i;
|
||||
|
||||
list_class = (*env)->GetObjectClass(env, device_list);
|
||||
if (list_class == NULL)
|
||||
return;
|
||||
add_method = (*env)->GetMethodID(env, list_class, "add", "(Ljava/lang/Object;)Z");
|
||||
if (add_method == NULL)
|
||||
return;
|
||||
|
||||
res = GetRawInputDeviceList(NULL, &num_devices, sizeof(RAWINPUTDEVICELIST));
|
||||
if ((UINT)-1 == res) {
|
||||
throwIOException(env, "Failed to get number of devices (%d)\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
devices = (RAWINPUTDEVICELIST *)malloc(num_devices*sizeof(RAWINPUTDEVICELIST));
|
||||
GetRawInputDeviceList(devices, &num_devices, sizeof(RAWINPUTDEVICELIST));
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
device = devices + i;
|
||||
device_object = newJObject(env, "net/java/games/input/RawDevice", "(Lnet/java/games/input/RawInputEventQueue;JI)V", queue, (jlong)(INT_PTR)device->hDevice, (jint)device->dwType);
|
||||
if (device_object == NULL) {
|
||||
free(devices);
|
||||
return;
|
||||
}
|
||||
(*env)->CallBooleanMethod(env, device_list, add_method, device_object);
|
||||
(*env)->DeleteLocalRef(env, device_object);
|
||||
}
|
||||
free(devices);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include "rawwinver.h"
|
||||
#include <windows.h>
|
||||
#include <jni.h>
|
||||
#include "net_java_games_input_RawInputEventQueue.h"
|
||||
#include "util.h"
|
||||
|
||||
static void handleMouseEvent(JNIEnv *env, jobject self, jmethodID add_method, LONG time, RAWINPUT *data) {
|
||||
(*env)->CallVoidMethod(env, self, add_method,
|
||||
(jlong)(INT_PTR)data->header.hDevice,
|
||||
(jlong)time,
|
||||
(jint)data->data.mouse.usFlags,
|
||||
(jint)data->data.mouse.usButtonFlags,
|
||||
/*
|
||||
* The Raw Input spec says that the usButtonData
|
||||
* is a signed value, if RI_MOUSE_WHEEL
|
||||
* is set in usFlags. However, usButtonData
|
||||
* is an unsigned value, for unknown reasons,
|
||||
* and since its only known use is the wheel
|
||||
* delta, we'll convert it to a signed value here
|
||||
*/
|
||||
(jint)(SHORT)data->data.mouse.usButtonData,
|
||||
(jlong)data->data.mouse.ulRawButtons,
|
||||
(jlong)data->data.mouse.lLastX,
|
||||
(jlong)data->data.mouse.lLastY,
|
||||
(jlong)data->data.mouse.ulExtraInformation
|
||||
);
|
||||
}
|
||||
|
||||
static void handleKeyboardEvent(JNIEnv *env, jobject self, jmethodID add_method, LONG time, RAWINPUT *data) {
|
||||
(*env)->CallVoidMethod(env, self, add_method,
|
||||
(jlong)(INT_PTR)data->header.hDevice,
|
||||
(jlong)time,
|
||||
(jint)data->data.keyboard.MakeCode,
|
||||
(jint)data->data.keyboard.Flags,
|
||||
(jint)data->data.keyboard.VKey,
|
||||
(jint)data->data.keyboard.Message,
|
||||
(jlong)data->data.keyboard.ExtraInformation
|
||||
);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_RawInputEventQueue_nRegisterDevices(JNIEnv *env, jclass unused, jint flags, jlong hwnd_addr, jobjectArray device_infos) {
|
||||
BOOL res;
|
||||
jclass device_info_class;
|
||||
jmethodID getUsage_method;
|
||||
jmethodID getUsagePage_method;
|
||||
RAWINPUTDEVICE *devices;
|
||||
RAWINPUTDEVICE *device;
|
||||
jsize num_devices = (*env)->GetArrayLength(env, device_infos);
|
||||
USHORT usage;
|
||||
USHORT usage_page;
|
||||
int i;
|
||||
HWND hwnd = (HWND)(INT_PTR)hwnd_addr;
|
||||
|
||||
/* res = GetRegisteredRawInputDevices(NULL, &num_devices, sizeof(RAWINPUTDEVICE));
|
||||
if (num_devices > 0) {
|
||||
devices = (RAWINPUTDEVICE *)malloc(num_devices*sizeof(RAWINPUTDEVICE));
|
||||
res = GetRegisteredRawInputDevices(devices, &num_devices, sizeof(RAWINPUTDEVICE));
|
||||
if (res == -1) {
|
||||
throwIOException(env, "Failed to get registered raw devices (%d)\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
printfJava(env, "from windows: registered: %d %d %p (of %d)\n", devices[i].usUsagePage, devices[i].usUsage, devices[i].hwndTarget, num_devices);
|
||||
}
|
||||
free(devices);
|
||||
}*/
|
||||
device_info_class = (*env)->FindClass(env, "net/java/games/input/RawDeviceInfo");
|
||||
if (device_info_class == NULL)
|
||||
return;
|
||||
getUsage_method = (*env)->GetMethodID(env, device_info_class, "getUsage", "()I");
|
||||
if (getUsage_method == NULL)
|
||||
return;
|
||||
getUsagePage_method = (*env)->GetMethodID(env, device_info_class, "getUsagePage", "()I");
|
||||
if (getUsagePage_method == NULL)
|
||||
return;
|
||||
devices = (RAWINPUTDEVICE *)malloc(num_devices*sizeof(RAWINPUTDEVICE));
|
||||
if (devices == NULL) {
|
||||
throwIOException(env, "Failed to allocate device structs\n");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
jobject device_obj = (*env)->GetObjectArrayElement(env, device_infos, i);
|
||||
if (device_obj == NULL) {
|
||||
free(devices);
|
||||
return;
|
||||
}
|
||||
usage = (*env)->CallIntMethod(env, device_obj, getUsage_method);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(devices);
|
||||
return;
|
||||
}
|
||||
usage_page = (*env)->CallIntMethod(env, device_obj, getUsagePage_method);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(devices);
|
||||
return;
|
||||
}
|
||||
device = devices + i;
|
||||
device->usUsagePage = usage_page;
|
||||
device->usUsage = usage;
|
||||
device->dwFlags = flags;
|
||||
device->hwndTarget = hwnd;
|
||||
}
|
||||
res = RegisterRawInputDevices(devices, num_devices, sizeof(RAWINPUTDEVICE));
|
||||
free(devices);
|
||||
if (!res)
|
||||
throwIOException(env, "Failed to register raw devices (%d)\n", GetLastError());
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_RawInputEventQueue_nPoll(JNIEnv *env, jobject self, jlong hwnd_handle) {
|
||||
MSG msg;
|
||||
HWND hwnd = (HWND)(INT_PTR)hwnd_handle;
|
||||
jmethodID addMouseEvent_method;
|
||||
jmethodID addKeyboardEvent_method;
|
||||
UINT input_size;
|
||||
RAWINPUT *input_data;
|
||||
LONG time;
|
||||
jclass self_class = (*env)->GetObjectClass(env, self);
|
||||
|
||||
if (self_class == NULL)
|
||||
return;
|
||||
addMouseEvent_method = (*env)->GetMethodID(env, self_class, "addMouseEvent", "(JJIIIJJJJ)V");
|
||||
if (addMouseEvent_method == NULL)
|
||||
return;
|
||||
addKeyboardEvent_method = (*env)->GetMethodID(env, self_class, "addKeyboardEvent", "(JJIIIIJ)V");
|
||||
if (addKeyboardEvent_method == NULL)
|
||||
return;
|
||||
if (GetMessage(&msg, hwnd, 0, 0) != 0) {
|
||||
if (msg.message != WM_INPUT) {
|
||||
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
|
||||
return; // ignore it
|
||||
}
|
||||
time = msg.time;
|
||||
if (GetRawInputData((HRAWINPUT)msg.lParam, RID_INPUT, NULL, &input_size, sizeof(RAWINPUTHEADER)) == (UINT)-1) {
|
||||
throwIOException(env, "Failed to get raw input data size (%d)\n", GetLastError());
|
||||
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
|
||||
return;
|
||||
}
|
||||
input_data = (RAWINPUT *)malloc(input_size);
|
||||
if (input_data == NULL) {
|
||||
throwIOException(env, "Failed to allocate input data buffer\n");
|
||||
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
|
||||
return;
|
||||
}
|
||||
if (GetRawInputData((HRAWINPUT)msg.lParam, RID_INPUT, input_data, &input_size, sizeof(RAWINPUTHEADER)) == (UINT)-1) {
|
||||
free(input_data);
|
||||
throwIOException(env, "Failed to get raw input data (%d)\n", GetLastError());
|
||||
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
|
||||
return;
|
||||
}
|
||||
switch (input_data->header.dwType) {
|
||||
case RIM_TYPEMOUSE:
|
||||
handleMouseEvent(env, self, addMouseEvent_method, time, input_data);
|
||||
break;
|
||||
case RIM_TYPEKEYBOARD:
|
||||
handleKeyboardEvent(env, self, addKeyboardEvent_method, time, input_data);
|
||||
break;
|
||||
default:
|
||||
/* ignore other types of message */
|
||||
break;
|
||||
}
|
||||
free(input_data);
|
||||
DefWindowProc(hwnd, msg.message, msg.wParam, msg.lParam);
|
||||
}
|
||||
}
|
||||
14
plugins/windows/src/main/native/raw/rawwinver.h
Normal file
14
plugins/windows/src/main/native/raw/rawwinver.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef RAWWINVER_H
|
||||
#define RAWWINVER_H
|
||||
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define WINVER 0x0501
|
||||
|
||||
#endif
|
||||
21
plugins/windows/src/main/native/winutil.c
Normal file
21
plugins/windows/src/main/native/winutil.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include "winutil.h"
|
||||
|
||||
jbyteArray wrapGUID(JNIEnv *env, const GUID *guid) {
|
||||
jbyteArray guid_array = (*env)->NewByteArray(env, sizeof(GUID));
|
||||
if (guid_array == NULL)
|
||||
return NULL;
|
||||
(*env)->SetByteArrayRegion(env, guid_array, 0, sizeof(GUID), (jbyte *)guid);
|
||||
return guid_array;
|
||||
}
|
||||
|
||||
void unwrapGUID(JNIEnv *env, const jobjectArray byte_array, GUID *guid) {
|
||||
(*env)->GetByteArrayRegion(env, byte_array, 0, sizeof(GUID), (jbyte *)guid);
|
||||
}
|
||||
|
||||
17
plugins/windows/src/main/native/winutil.h
Normal file
17
plugins/windows/src/main/native/winutil.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _WINUTIL_H
|
||||
#define _WINUTIL_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <jni.h>
|
||||
|
||||
extern jbyteArray wrapGUID(JNIEnv *env, const GUID *guid);
|
||||
extern void unwrapGUID(JNIEnv *env, const jobjectArray byte_array, GUID *guid);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue