Refactor the sources

This commit is contained in:
Endolf 2018-05-09 20:38:48 +01:00
parent c71f96a708
commit 682ebbaf69
46 changed files with 5 additions and 12 deletions

View file

@ -0,0 +1 @@
/net_java_games_input_DummyWindow.h

View 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>

View file

@ -0,0 +1,3 @@
/net_java_games_input_IDirectInput.h
/net_java_games_input_IDirectInputDevice.h
/net_java_games_input_IDirectInputEffect.h

View 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

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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(&params, sizeof(params));
params.dwSize = sizeof(params);
params.dwGain = gain;
return IDirectInputEffect_SetParameters(ppdeff, &params, 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);
}

View file

@ -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());
}
}

View 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

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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);
}
}

View 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

View 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);
}

View 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