mirror of
https://github.com/shadowfacts/jinput-arm64.git
synced 2026-04-21 06:14:11 +00:00
Initial release of native library
This commit is contained in:
parent
c2688c3ae8
commit
24d639f5be
1 changed files with 716 additions and 0 deletions
716
plugins/OSX/src/native/jinputjnilib.c
Normal file
716
plugins/OSX/src/native/jinputjnilib.c
Normal file
|
|
@ -0,0 +1,716 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistribution in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materails provided with the distribution.
|
||||
*
|
||||
* Neither the name Sun Microsystems, Inc. or the names of the contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind.
|
||||
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
|
||||
* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
||||
* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
|
||||
* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
|
||||
* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
|
||||
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
|
||||
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
|
||||
* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
|
||||
* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
|
||||
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* You acknowledge that this software is not designed or intended for us in
|
||||
* the design, construction, operation or maintenance of any nuclear facility
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sysexits.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_error.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/IOCFPlugIn.h>
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
#include <IOKit/hid/IOHIDKeys.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
#include "net_java_games_input_OSXEnvironmentPlugin.h"
|
||||
|
||||
Boolean init( JNIEnv * env );
|
||||
void createMasterPort();
|
||||
void disposeMasterPort();
|
||||
|
||||
|
||||
void createHIDDevice(io_object_t hidDevice, IOHIDDeviceInterface ***hidDeviceInterface);
|
||||
IOReturn openDevice(IOHIDDeviceInterface ***hidDeviceInterface);
|
||||
IOReturn closeDevice(IOHIDDeviceInterface ***hidDeviceInterface);
|
||||
|
||||
|
||||
Boolean showDictionaryElement (CFDictionaryRef dictionary, CFStringRef key);
|
||||
void showProperty(const void * key, const void * value);
|
||||
void displayCFProperty(CFStringRef object, CFTypeRef value);
|
||||
void CFObjectShow( CFTypeRef value );
|
||||
void CFObjectSend( CFTypeRef value );
|
||||
|
||||
jclass CLASS_JNIWrapper = NULL;
|
||||
jmethodID MID_AddDevice = NULL;
|
||||
jmethodID MID_AddControllerElement = NULL;
|
||||
mach_port_t masterPort = NULL;
|
||||
io_iterator_t hidObjectIterator;
|
||||
int gElementIndex;
|
||||
|
||||
long elementCookie;
|
||||
long collectionType;
|
||||
long min;
|
||||
long max;
|
||||
long scaledMin;
|
||||
long scaledMax;
|
||||
long size;
|
||||
jboolean isRelative;
|
||||
jboolean isWrapping;
|
||||
jboolean isNonLinear;
|
||||
|
||||
|
||||
JNIEnv * lpEnv;
|
||||
jlong lpDevice;
|
||||
|
||||
|
||||
|
||||
|
||||
Boolean showDictionaryElement (CFDictionaryRef dictionary, CFStringRef key)
|
||||
{
|
||||
CFTypeRef value = CFDictionaryGetValue (dictionary, key);
|
||||
if (value)
|
||||
{
|
||||
const char * c = CFStringGetCStringPtr (key, CFStringGetSystemEncoding ());
|
||||
if (c)
|
||||
{
|
||||
printf ("%s", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
CFIndex bufferSize = CFStringGetLength (key) + 1;
|
||||
char * buffer = (char *)malloc (bufferSize);
|
||||
if (buffer)
|
||||
{
|
||||
if (CFStringGetCString (key, buffer, bufferSize, CFStringGetSystemEncoding ()))
|
||||
printf ("%s", buffer);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
printf("=");
|
||||
|
||||
CFObjectShow( value );
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
return (value != NULL);
|
||||
}
|
||||
|
||||
static void showCFArray (const void * value, void * parameter)
|
||||
{
|
||||
if (CFGetTypeID (value) != CFDictionaryGetTypeID ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CFObjectShow(value);
|
||||
}
|
||||
|
||||
void CFObjectShow( CFTypeRef value )
|
||||
{
|
||||
CFTypeID type = CFGetTypeID(value);
|
||||
if (type == CFArrayGetTypeID())
|
||||
{
|
||||
|
||||
printf("Array Type\n");
|
||||
CFRange range = {0, CFArrayGetCount (value)};
|
||||
CFIndex savedIndex = gElementIndex;
|
||||
|
||||
//Show an element array containing one or more element dictionaries
|
||||
gElementIndex = 0; //Reset index to zero
|
||||
CFArrayApplyFunction (value, range, showCFArray, 0);
|
||||
|
||||
gElementIndex = savedIndex;
|
||||
}
|
||||
else if (type == CFBooleanGetTypeID())
|
||||
{
|
||||
printf(CFBooleanGetValue(value) ? "true" : "false");
|
||||
}
|
||||
else if (type == CFDictionaryGetTypeID())
|
||||
{
|
||||
printf("Map\n");
|
||||
|
||||
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementCookieKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementCollectionTypeKey));
|
||||
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementMinKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementMaxKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementScaledMinKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementScaledMaxKey));
|
||||
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementSizeKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementIsRelativeKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementIsWrappingKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementIsNonLinearKey));
|
||||
#ifdef kIOHIDElementHasPreferredStateKey
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementHasPreferredStateKey));
|
||||
#else
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementHasPreferedStateKey));
|
||||
#endif
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementHasNullStateKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementVendorSpecificKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementUnitKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementUnitExponentKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementNameKey));
|
||||
showDictionaryElement (value, CFSTR(kIOHIDElementKey));
|
||||
|
||||
printf("\n\n\n");
|
||||
}
|
||||
else if (type == CFNumberGetTypeID())
|
||||
{
|
||||
long number;
|
||||
if (CFNumberGetValue (value, kCFNumberLongType, &number))
|
||||
{
|
||||
printf("0x%lx (%ld)", number, number);
|
||||
}
|
||||
}
|
||||
else if (type == CFStringGetTypeID())
|
||||
{
|
||||
const char * c = CFStringGetCStringPtr (value, CFStringGetSystemEncoding ());
|
||||
if (c)
|
||||
{
|
||||
printf ("%s", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
CFIndex bufferSize = CFStringGetLength (value) + 1;
|
||||
char * buffer = (char *)malloc (bufferSize);
|
||||
if (buffer)
|
||||
{
|
||||
if (CFStringGetCString (value, buffer, bufferSize, CFStringGetSystemEncoding ()))
|
||||
{
|
||||
printf ("%s", buffer);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
Boolean init(JNIEnv* env)
|
||||
{
|
||||
CLASS_JNIWrapper = (*env)->FindClass(env,"net/java/games/input/OSXEnvironmentPlugin");
|
||||
if ( CLASS_JNIWrapper == NULL )
|
||||
{
|
||||
printf("Class OSXEnvironmentPlugin not found... \n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MID_AddDevice = (*env)->GetMethodID(env, CLASS_JNIWrapper, "addController", "(JLjava/lang/String;I)V");
|
||||
if (MID_AddDevice == NULL)
|
||||
{
|
||||
printf("Method addController not found... \n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MID_AddControllerElement = (*env)->GetMethodID(env, CLASS_JNIWrapper, "addControllerElement", "(JJILjava/lang/String;IIIIIZZZZZ)V");
|
||||
if (MID_AddDeviceElement == NULL)
|
||||
{
|
||||
printf("Method addControllerElement not found... \n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void createMasterPort()
|
||||
{
|
||||
IOReturn ioReturnValue = kIOReturnSuccess;
|
||||
|
||||
//Get a Mach port to initiate communication with I/O Kit.
|
||||
//
|
||||
ioReturnValue = IOMasterPort(bootstrap_port, &masterPort);
|
||||
}
|
||||
|
||||
void disposeMasterPort()
|
||||
{
|
||||
//Free master port if we created one.
|
||||
//
|
||||
if (masterPort)
|
||||
{
|
||||
mach_port_deallocate(mach_task_self(), masterPort);
|
||||
}
|
||||
}
|
||||
|
||||
void createHIDDevice( io_object_t hidDevice, IOHIDDeviceInterface ***hidDeviceInterface )
|
||||
{
|
||||
io_name_t className;
|
||||
IOCFPlugInInterface **plugInInterface = NULL;
|
||||
HRESULT plugInResult = S_OK;
|
||||
SInt32 score = 0;
|
||||
IOReturn ioReturnValue = kIOReturnSuccess;
|
||||
|
||||
ioReturnValue = IOObjectGetClass(hidDevice, className);
|
||||
if ( ioReturnValue != kIOReturnSuccess )
|
||||
{
|
||||
printf("Failed to getIOObject class name.");
|
||||
}
|
||||
|
||||
printf("Found device type %s\n", className);
|
||||
|
||||
ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice,
|
||||
kIOHIDDeviceUserClientTypeID,
|
||||
kIOCFPlugInInterfaceID,
|
||||
&plugInInterface,
|
||||
&score);
|
||||
|
||||
if (ioReturnValue == kIOReturnSuccess)
|
||||
{
|
||||
//Call a method of the intermediate plug-in to create the device
|
||||
//interface
|
||||
plugInResult = (*plugInInterface)->QueryInterface(plugInInterface,
|
||||
CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
|
||||
(LPVOID) hidDeviceInterface);
|
||||
if ( plugInResult != S_OK )
|
||||
{
|
||||
printf("Couldn't create HID class device interface");
|
||||
}
|
||||
|
||||
(*plugInInterface)->Release(plugInInterface);
|
||||
}
|
||||
}
|
||||
|
||||
IOReturn openDevice(IOHIDDeviceInterface ***hidDeviceInterface)
|
||||
{
|
||||
IOReturn ioReturnValue = kIOReturnSuccess;
|
||||
|
||||
//todo, change this to be controlled from the java layer at each device
|
||||
//
|
||||
ioReturnValue = (**hidDeviceInterface)->open(*hidDeviceInterface, 0 );
|
||||
if ( ioReturnValue != kIOReturnSuccess )
|
||||
{
|
||||
printf("Unable to open device - return [%d]\n", ioReturnValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Successfully opened device \n");
|
||||
}
|
||||
|
||||
return ioReturnValue;
|
||||
}
|
||||
|
||||
IOReturn closeDevice(IOHIDDeviceInterface ***hidDeviceInterface)
|
||||
{
|
||||
IOReturn ioReturnValue = kIOReturnSuccess;
|
||||
|
||||
ioReturnValue = (**hidDeviceInterface)->close(*hidDeviceInterface);
|
||||
if ( ioReturnValue != kIOReturnSuccess )
|
||||
{
|
||||
printf("Unable to close device - return [%d]\n", ioReturnValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Successfully closed device \n");
|
||||
}
|
||||
|
||||
// release the device interface
|
||||
//
|
||||
(**hidDeviceInterface)->Release(*hidDeviceInterface);
|
||||
|
||||
return ioReturnValue;
|
||||
}
|
||||
|
||||
void addControllerElements( CFMutableDictionaryRef dictionary, CFStringRef key )
|
||||
{
|
||||
printf("Adding controller elements\n");
|
||||
|
||||
CFTypeRef value = CFDictionaryGetValue (dictionary, key);
|
||||
if (value)
|
||||
{
|
||||
CFTypeID type = CFGetTypeID(value);
|
||||
|
||||
CFRange range = {0, CFArrayGetCount (value)};
|
||||
CFIndex savedIndex = gElementIndex;
|
||||
|
||||
//Show an element array containing one or more element dictionaries
|
||||
gElementIndex = 0; //Reset index to zero
|
||||
CFArrayApplyFunction (value, range, sendCFArray, 0);
|
||||
|
||||
gElementIndex = savedIndex;
|
||||
}
|
||||
}
|
||||
|
||||
static void sendCFArray(const void * value, void * parameter)
|
||||
{
|
||||
if (CFGetTypeID (value) != CFDictionaryGetTypeID ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CFObjectSend(value);
|
||||
}
|
||||
|
||||
void CFObjectSend( CFTypeRef value )
|
||||
{
|
||||
CFTypeID type = CFGetTypeID(value);
|
||||
if (type == CFArrayGetTypeID())
|
||||
{
|
||||
|
||||
printf("Array Type\n");
|
||||
CFRange range = {0, CFArrayGetCount (value)};
|
||||
CFIndex savedIndex = gElementIndex;
|
||||
|
||||
//Show an element array containing one or more element dictionaries
|
||||
gElementIndex = 0; //Reset index to zero
|
||||
CFArrayApplyFunction (value, range, sendCFArray, 0);
|
||||
|
||||
gElementIndex = savedIndex;
|
||||
}
|
||||
else if (type == CFDictionaryGetTypeID())
|
||||
{
|
||||
printf("Sending Map\n");
|
||||
|
||||
|
||||
CFTypeRef val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementCookieKey) );
|
||||
if ( val )
|
||||
{
|
||||
CFNumberGetValue ( val , kCFNumberLongType, &elementCookie);
|
||||
printf("ElementCookie - 0x%lx (%ld) \n", elementCookie, elementCookie);
|
||||
}
|
||||
|
||||
val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementCollectionTypeKey) );
|
||||
if ( val )
|
||||
{
|
||||
CFNumberGetValue ( val, kCFNumberLongType, &collectionType);
|
||||
printf("collection Type - 0x%lx (%ld) \n", collectionType, collectionType);
|
||||
}
|
||||
|
||||
val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementMinKey) );
|
||||
if ( val )
|
||||
{
|
||||
CFNumberGetValue ( val, kCFNumberLongType, &min);
|
||||
printf("min - 0x%lx (%ld) \n", min, min);
|
||||
}
|
||||
|
||||
val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementMaxKey) );
|
||||
if ( val )
|
||||
{
|
||||
CFNumberGetValue ( val, kCFNumberLongType, &max);
|
||||
printf("max - 0x%lx (%ld) \n", max, max);
|
||||
}
|
||||
|
||||
val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementScaledMinKey) );
|
||||
if ( val )
|
||||
{
|
||||
CFNumberGetValue ( val, kCFNumberLongType, &scaledMin);
|
||||
printf("scaledMin - 0x%lx (%ld) \n", scaledMin, scaledMin);
|
||||
}
|
||||
|
||||
val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementScaledMaxKey) );
|
||||
if ( val )
|
||||
{
|
||||
CFNumberGetValue ( val, kCFNumberLongType, &scaledMax);
|
||||
printf("scaledMax - 0x%lx (%ld) \n", scaledMax, scaledMax);
|
||||
}
|
||||
|
||||
val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementSizeKey) );
|
||||
if ( val )
|
||||
{
|
||||
CFNumberGetValue ( val, kCFNumberLongType, &size);
|
||||
printf("Size - 0x%lx (%ld) \n", size, size);
|
||||
}
|
||||
|
||||
|
||||
printf("End of element definition \n");
|
||||
|
||||
/*
|
||||
|
||||
jboolean isRelative;
|
||||
isRelative = (CFBooleanGetValue(value) ? JNI_TRUE : JNI_FALSE);
|
||||
|
||||
|
||||
jboolean isWrapping;
|
||||
isWrapping = (CFBooleanGetValue(value) ? JNI_TRUE : JNI_FALSE);
|
||||
|
||||
jboolean isNonLinear;
|
||||
isNonLinear = (CFBooleanGetValue(value) ? JNI_TRUE : JNI_FALSE);
|
||||
*/
|
||||
#ifdef kIOHIDElementHasPreferredStateKey
|
||||
//showDictionaryElement (value, CFSTR(kIOHIDElementHasPreferredStateKey));
|
||||
#else
|
||||
//showDictionaryElement (value, CFSTR(kIOHIDElementHasPreferedStateKey));
|
||||
#endif
|
||||
//showDictionaryElement (value, CFSTR(kIOHIDElementHasNullStateKey));
|
||||
//showDictionaryElement (value, CFSTR(kIOHIDElementVendorSpecificKey));
|
||||
|
||||
//showDictionaryElement (value, CFSTR(kIOHIDElementKey));
|
||||
|
||||
//showDictionaryElement (value, CFSTR(kIOHIDElementKey));
|
||||
|
||||
CFTypeRef object = CFDictionaryGetValue (value, CFSTR(kIOHIDElementKey));
|
||||
if (object)
|
||||
{
|
||||
CFObjectSend( object );
|
||||
}
|
||||
|
||||
printf("\n\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: net_java_games_input_OSXEnvironmentPlugin
|
||||
* Method: hidCreate
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_hidCreate
|
||||
(JNIEnv * env, jobject obj)
|
||||
{
|
||||
if ( init( env ) )
|
||||
{
|
||||
createMasterPort();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Class: net_java_games_input_OSXEnvironmentPlugin
|
||||
* Method: hidDispose
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_hidDispose
|
||||
(JNIEnv * env, jobject obj)
|
||||
{
|
||||
disposeMasterPort();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: net_java_games_input_OSXEnvironmentPlugin
|
||||
* Method: enumDevices
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_enumDevices
|
||||
(JNIEnv * env, jobject obj)
|
||||
{
|
||||
CFMutableDictionaryRef hidMatchDictionary = NULL;
|
||||
IOReturn ioReturnValue = kIOReturnSuccess;
|
||||
Boolean noMatchingDevices = false;
|
||||
|
||||
// Set up a matching dictionary to search the I/O Registry by class
|
||||
// name for all HID class devices
|
||||
//
|
||||
hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
|
||||
|
||||
// Now search I/O Registry for matching devices.
|
||||
//
|
||||
ioReturnValue = IOServiceGetMatchingServices(masterPort, hidMatchDictionary, &hidObjectIterator);
|
||||
|
||||
noMatchingDevices = ((ioReturnValue != kIOReturnSuccess) | (hidObjectIterator == NULL));
|
||||
|
||||
// If search is unsuccessful, print message and hang.
|
||||
//
|
||||
if (noMatchingDevices)
|
||||
{
|
||||
printf("No matching HID class devices found.");
|
||||
}
|
||||
|
||||
// IOServiceGetMatchingServices consumes a reference to the
|
||||
// dictionary, so we don't need to release the dictionary ref.
|
||||
//
|
||||
hidMatchDictionary = NULL;
|
||||
|
||||
io_object_t hidDevice = NULL;
|
||||
IOHIDDeviceInterface **hidDeviceInterface = NULL;
|
||||
CFMutableDictionaryRef properties = 0;
|
||||
char path[512];
|
||||
kern_return_t result;
|
||||
|
||||
|
||||
while ((hidDevice = IOIteratorNext(hidObjectIterator)))
|
||||
{
|
||||
result = IORegistryEntryGetPath(hidDevice, kIOServicePlane, path);
|
||||
|
||||
if ( result == KERN_SUCCESS )
|
||||
{
|
||||
result = IORegistryEntryCreateCFProperties(hidDevice,
|
||||
&properties,
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
}
|
||||
|
||||
if ((result == KERN_SUCCESS) && properties)
|
||||
{
|
||||
//showDictionaryElement(properties, CFSTR(kIOHIDTransportKey));
|
||||
//showDictionaryElement(properties, CFSTR(kIOHIDVendorKey));
|
||||
//printf("ProductID: "); showDictionaryElement(properties, CFSTR(kIOHIDProductIDKey));
|
||||
//printf("VersionNumber: "); showDictionaryElement(properties, CFSTR(kIOHIDVersionNumberKey));
|
||||
//printf("Manufacturer: "); showDictionaryElement(properties, CFSTR(kIOHIDManufacturerKey));
|
||||
//printf("ProductKey: "); showDictionaryElement(properties, CFSTR(kIOHIDProductKey));
|
||||
//printf("SerialNumber: "); showDictionaryElement(properties, CFSTR(kIOHIDSerialNumberKey));
|
||||
//showDictionaryElement(properties, CFSTR(kIOHIDLocationIDKey));
|
||||
//printf("PrimaryUsage: "); showDictionaryElement(properties, CFSTR(kIOHIDPrimaryUsageKey));
|
||||
//showDictionaryElement(properties, CFSTR(kIOHIDPrimaryUsagePageKey));
|
||||
//showDictionaryElement(properties, CFSTR(kIOHIDElementKey));
|
||||
|
||||
|
||||
|
||||
// get the product name
|
||||
//
|
||||
CFTypeRef productName = CFDictionaryGetValue (properties, CFSTR(kIOHIDProductKey));
|
||||
|
||||
// get the usage for this product
|
||||
//
|
||||
long usage;
|
||||
CFNumberGetValue ( CFDictionaryGetValue( properties, CFSTR(kIOHIDPrimaryUsageKey) ), kCFNumberLongType, &usage);
|
||||
|
||||
|
||||
createHIDDevice( hidDevice, &hidDeviceInterface );
|
||||
|
||||
IOObjectRelease( hidDevice );
|
||||
|
||||
if ( hidDeviceInterface != NULL )
|
||||
{
|
||||
(*env)->CallVoidMethod(env, obj, MID_AddDevice,
|
||||
(jlong)(long)hidDeviceInterface,
|
||||
(*env)->NewStringUTF( env, CFStringGetCStringPtr( productName, CFStringGetSystemEncoding()) ),
|
||||
(jint)usage );
|
||||
lpEnv = env;
|
||||
lpDevice = (jlong)(long)hidDeviceInterface;
|
||||
|
||||
addControllerElements( properties, CFSTR(kIOHIDElementKey) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Release the properties dictionary
|
||||
CFRelease(properties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IOObjectRelease(hidObjectIterator);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: net_java_games_input_OSXEnvironmentPlugin
|
||||
* Method: openDevice
|
||||
* Signature: (JI)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_openDevice
|
||||
(JNIEnv * env, jobject obj, jlong lpDevice, jint queueDepth)
|
||||
{
|
||||
IOHIDDeviceInterface **hidDeviceInterface = NULL;
|
||||
hidDeviceInterface = (IOHIDDeviceInterface **) (long)lpDevice;
|
||||
openDevice( &hidDeviceInterface );
|
||||
|
||||
|
||||
IOHIDQueueInterface **queue = NULL;
|
||||
queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface);
|
||||
|
||||
if (queue)
|
||||
{
|
||||
// create a queue and specify how deep they want the input queue to be
|
||||
//
|
||||
(*queue)->create( queue, 0, (int)queueDepth );
|
||||
printf("InputQueue created %lx with depth %d \n", queue, (int)queueDepth );
|
||||
|
||||
// todo - add the buttons/keys we want to receive from the queue
|
||||
|
||||
|
||||
// start the input queue
|
||||
//
|
||||
(*queue)->start( queue );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unable to create queue for device! \n");
|
||||
}
|
||||
|
||||
return (jlong)(long)queue;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: net_java_games_input_OSXEnvironmentPlugin
|
||||
* Method: closeDevice
|
||||
* Signature: (JJ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_closeDevice
|
||||
(JNIEnv * env, jobject obj, jlong lpDevice, jlong lpQueue)
|
||||
{
|
||||
IOHIDDeviceInterface **hidDeviceInterface = NULL;
|
||||
hidDeviceInterface = (IOHIDDeviceInterface **) (long)lpDevice;
|
||||
|
||||
IOHIDQueueInterface **queue = NULL;
|
||||
queue = (IOHIDQueueInterface **)(long)lpQueue;
|
||||
|
||||
// stop the queue
|
||||
//
|
||||
(*queue)->stop(queue);
|
||||
|
||||
// dispose of the queue
|
||||
//
|
||||
(*queue)->dispose(queue);
|
||||
|
||||
// release the queue
|
||||
//
|
||||
(*queue)->Release(queue);
|
||||
|
||||
// close the input device
|
||||
//
|
||||
closeDevice( &hidDeviceInterface );
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: net_java_games_input_OSXEnvironmentPlugin
|
||||
* Method: pollDevice
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_pollDevice
|
||||
(JNIEnv * env, jobject obj, jlong lpQueue)
|
||||
{
|
||||
IOHIDEventStruct event;
|
||||
|
||||
IOHIDQueueInterface **queue = NULL;
|
||||
queue = (IOHIDQueueInterface **)(long)lpQueue;
|
||||
|
||||
AbsoluteTime zeroTime = {0,0};
|
||||
|
||||
HRESULT result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
|
||||
if ( result )
|
||||
{
|
||||
printf("Queue getNextEvent result: %lx\n", result );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Queue event[%lx] %ld\n", (unsigned long) event.elementCookie, event.value );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue