aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/OSX/src/native
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/OSX/src/native')
-rw-r--r--plugins/OSX/src/native/build.xml80
-rw-r--r--plugins/OSX/src/native/jinputjnilib.c839
-rw-r--r--plugins/OSX/src/native/macosxutil.c197
-rw-r--r--plugins/OSX/src/native/macosxutil.h48
-rw-r--r--plugins/OSX/src/native/net_java_games_input_OSXHIDDevice.c118
-rw-r--r--plugins/OSX/src/native/net_java_games_input_OSXHIDDeviceIterator.c143
-rw-r--r--plugins/OSX/src/native/net_java_games_input_OSXHIDQueue.c135
7 files changed, 703 insertions, 857 deletions
diff --git a/plugins/OSX/src/native/build.xml b/plugins/OSX/src/native/build.xml
index b88c856..9b338da 100644
--- a/plugins/OSX/src/native/build.xml
+++ b/plugins/OSX/src/native/build.xml
@@ -1,23 +1,67 @@
<?xml version="1.0" ?>
<project name="OS X Plugin, Native code" basedir="." default="compileNativeJinputLib">
- <description>OSX JInput Native Plugin</description>
- <property name="src" location="src" />
- <property name="build" location="classes" />
- <property name="dist" location="../../dist" />
- <property name="plugins" location="plugins" />
-
- <target name="init">
- <mkdir dir="build"/>
- </target>
+ <description>OSX JInput Native Plugin</description>
- <target name="compileNativeJinputLib" depends="init">
- <exec dir="." executable="cc" os="Mac OS X">
-
- <arg line="-c -I${java.home}/include jinputjnilib.c"/>
- </exec>
- <exec dir="." executable="cc" os="Mac OS X">
- <arg line="-bundle -o libjinput.jnilib jinputjnilib.o -framework JavaVM -framework CoreFoundation -framework IOKit "/>
- </exec>
- </target>
+ <target name="init">
+ <mkdir dir="universal"/>
+ <mkdir dir="legacy"/>
+ </target>
+
+ <target name="clean">
+ <delete failonerror="false">
+ <fileset dir="universal"/>
+ <fileset dir="legacy"/>
+ </delete>
+ </target>
+ <target name="compile">
+ <apply dir="${dstdir}" executable="${compiler}" os="Mac OS X" skipemptyfilesets="true" failonerror="true" dest="${dstdir}">
+ <arg line="${cflags} -O2 -Wall -c -fPIC -I${sdkroot}/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers -I../../../../common/src/native -I.."/>
+ <mapper type="glob" from="*.c" to="*.o"/>
+ <fileset dir="." includes="*.c"/>
+ <fileset dir="../../../common/src/native" includes="*.c"/>
+ </apply>
+ </target>
+
+ <target name="link">
+ <apply dir="." parallel="true" executable="${linker}" os="Mac OS X" failonerror="true">
+ <arg line="${linkerflags} -dynamiclib -o ${libname} -framework JavaVM -framework CoreFoundation -framework IOKit -framework CoreServices"/>
+ <fileset dir="${objdir}" includes="*.o"/>
+ </apply>
+ <apply dir="." parallel="true" executable="strip" os="Mac OS X" failonerror="true">
+ <arg line="-S -X"/>
+ <fileset dir="." includes="*.jnilib"/>
+ </apply>
+ </target>
+
+ <target name="compileNativeJinputLib" depends="init">
+ <property name="universal_sdkroot" location="/Developer/SDKs/MacOSX10.4u.sdk"/>
+ <property name="legacy_sdkroot" location="/Developer/SDKs/MacOSX10.3.9.sdk"/>
+ <property name="universal_flags" value="-isysroot ${universal_sdkroot} -arch i386 -arch ppc"/>
+ <antcall target="compile">
+ <param name="dstdir" location="universal"/>
+ <param name="compiler" value="gcc-4.0"/>
+ <param name="sdkroot" location="${universal_sdkroot}"/>
+ <param name="cflags" value="${universal_flags}"/>
+ </antcall>
+ <antcall target="link">
+ <param name="objdir" location="universal"/>
+ <param name="libname" value="libjinput-osx.jnilib"/>
+ <param name="linker" value="gcc-4.0"/>
+ <!-- <param name="linkerflags" value="${universal_flags} -Wl,-syslibroot,${universal_sdkroot}"/>-->
+ <param name="linkerflags" value="${universal_flags}"/>
+ </antcall>
+ <antcall target="compile">
+ <param name="dstdir" location="legacy"/>
+ <param name="compiler" value="gcc-3.3"/>
+ <param name="sdkroot" location="${legacy_sdkroot}"/>
+ <param name="cflags" value=""/>
+ </antcall>
+ <antcall target="link">
+ <param name="objdir" location="legacy"/>
+ <param name="libname" value="libjinput-osx-legacy.jnilib"/>
+ <param name="linker" value="gcc-3.3"/>
+ <param name="linkerflags" value=""/>
+ </antcall>
+ </target>
</project>
diff --git a/plugins/OSX/src/native/jinputjnilib.c b/plugins/OSX/src/native/jinputjnilib.c
deleted file mode 100644
index 86c7347..0000000
--- a/plugins/OSX/src/native/jinputjnilib.c
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
- * %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_AddController = NULL;
-jmethodID MID_AddControllerElement = NULL;
-mach_port_t masterPort = NULL;
-io_iterator_t hidObjectIterator;
-
-long elementCookie;
-long elementType;
-long usage;
-long usagePage;
-long min;
-long max;
-long scaledMin;
-long scaledMax;
-long size;
-jboolean isRelative;
-jboolean isWrapping;
-jboolean isNonLinear;
-
-
-JNIEnv * lpEnv;
-jlong lpDevice;
-jobject lpObj;
-jboolean completeElement = JNI_FALSE;
-
-
-
-
-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())
- {
- CFRange range = {0, CFArrayGetCount (value)};
-
- //Show an element array containing one or more element dictionaries
- CFArrayApplyFunction (value, range, showCFArray, 0);
- }
- 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_AddController = (*env)->GetMethodID(env, CLASS_JNIWrapper, "addController", "(JLjava/lang/String;I)V");
- if (MID_AddController == NULL)
- {
- printf("Method addController not found... \n");
- return FALSE;
- }
-
- MID_AddControllerElement = (*env)->GetMethodID(env, CLASS_JNIWrapper, "addControllerElement", "(JJIIIIIIIIZZZZZ)V");
- if (MID_AddControllerElement == 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 get IOObject 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;
-}
-
-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())
- {
- CFRange range = {0, CFArrayGetCount (value)};
-
- //Show an element array containing one or more element dictionaries
- CFArrayApplyFunction (value, range, sendCFArray, 0);
- }
- 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(kIOHIDElementTypeKey) );
- if ( val )
- {
- CFNumberGetValue ( val, kCFNumberLongType, &elementType);
- printf("element Type - 0x%lx (%ld) \n", elementType, elementType);
- }
-
- val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementUsageKey) );
- if ( val )
- {
- CFNumberGetValue ( val, kCFNumberLongType, &usage);
- printf("usage - 0x%lx (%ld) \n", usage, usage);
- }
-
- val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementUsagePageKey) );
- if ( val )
- {
- CFNumberGetValue ( val, kCFNumberLongType, &usagePage);
- printf("usage page- 0x%lx (%ld) \n", usagePage, usagePage);
- }
-
- 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);
- }
-
- jboolean isRelative = JNI_FALSE;
- val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementIsRelativeKey) );
- if ( val )
- {
- isRelative = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE);
- }
-
-
- jboolean isWrapping = JNI_FALSE;
- val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementIsWrappingKey) );
- if ( val )
- {
- isWrapping = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE);
- }
-
-
- jboolean isNonLinear = JNI_FALSE;
- val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementIsNonLinearKey) );
- if ( val )
- {
- isNonLinear = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE);
- }
-
-
- jboolean hasPreferredState = JNI_FALSE;
-#ifdef kIOHIDElementHasPreferredStateKey
- val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementHasPreferredStateKey) );
- if ( val )
- {
- hasPreferredState = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE);
- }
-#else
- val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementHasPreferedStateKey) );
- if ( val )
- {
- hasPreferredState = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE);
- }
-#endif
-
- jboolean hasNullState = JNI_FALSE;
- val = CFDictionaryGetValue( value, CFSTR(kIOHIDElementHasNullStateKey) );
- if ( val )
- {
- hasNullState = (CFBooleanGetValue(val) ? JNI_TRUE : JNI_FALSE);
- }
-
- (*lpEnv)->CallVoidMethod(lpEnv, lpObj, MID_AddControllerElement,
- (jlong)(long)lpDevice,
- (jlong)(long)elementCookie,
- (jint)(long)elementType,
- (jint)(long)usage,
- (jint)(long)usagePage,
- (jint)(long)min,
- (jint)(long)max,
- (jint)(long)scaledMin,
- (jint)(long)scaledMax,
- (jint)(long)size,
- (jboolean)isRelative,
- (jboolean)isWrapping,
- (jboolean)isNonLinear,
- (jboolean)hasPreferredState,
- (jboolean)hasNullState);
-
-// printf("End of element definition \n");
-
-
-
- CFTypeRef object = CFDictionaryGetValue (value, CFSTR(kIOHIDElementKey));
- if (object)
- {
- CFObjectSend( object );
- }
-
- printf("\n\n\n");
- }
-}
-
-void addControllerElements( CFMutableDictionaryRef dictionary, CFStringRef key )
-{
- printf("Adding controller elements\n");
-
- CFTypeRef value = CFDictionaryGetValue (dictionary, key);
- if (value)
- {
- CFRange range = {0, CFArrayGetCount (value)};
- CFArrayApplyFunction (value, range, sendCFArray, 0);
- }
-}
-
-/*
- * 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)
-{
-
- lpEnv = env;
- lpObj = 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 .
- //
- if (noMatchingDevices)
- {
- printf("No matching HID class devices found.");
- return;
- }
-
- // 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_AddController,
- (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", (long) queue, (int)queueDepth );
-
- // 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)I
- */
-JNIEXPORT jint 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};
- IOReturn ioReturnValue = kIOReturnSuccess;
-
- ioReturnValue = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
- if ( ioReturnValue == kIOReturnSuccess )
- {
- printf("Queue getNextEvent return value: %ld\n", (long)ioReturnValue );
- }
- else
- {
- printf("Queue event[%lx] %ld\n", (unsigned long) event.elementCookie, event.value );
- }
-
- return (jint) event.value;
-}
-
-/*
- * Class: net_java_games_input_OSXEnvironmentPlugin
- * Method: pollDevice
- * Signature: (JJ)I
- */
-JNIEXPORT jint JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_pollElement
- (JNIEnv * env, jobject obj, jlong lpDevice, jlong hidCookie)
-{
- IOHIDDeviceInterface **hidDeviceInterface = NULL;
- hidDeviceInterface = (IOHIDDeviceInterface **) (long)lpDevice;
-
- IOHIDElementCookie cookie = (IOHIDElementCookie)(long)hidCookie;
-
- IOHIDEventStruct event;
-
- IOReturn ioReturnValue = kIOReturnSuccess;
-
- ioReturnValue = (*hidDeviceInterface)->getElementValue(hidDeviceInterface, cookie, &event);
- if ( ioReturnValue == kIOReturnSuccess )
- {
- printf("Queue getNextEvent return value: %ld\n", (long)ioReturnValue );
- }
- else
- {
- printf("Queue event[%lx] %ld\n", (unsigned long) event.elementCookie, event.value );
- }
-
- return (jint) event.value;
-}
-
-
-/*
- * Class: net_java_games_input_OSXEnvironmentPlugin
- * Method: registerDeviceElement
- * Signature: (JJ)V
- */
-JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_registerDeviceElement
- (JNIEnv * env, jobject obj, jlong lpQueue, jlong hidCookie)
-{
- IOHIDQueueInterface **queue = NULL;
- queue = (IOHIDQueueInterface **)(long)lpQueue;
-
- IOHIDElementCookie cookie = (IOHIDElementCookie)(long)hidCookie;
- IOReturn ioReturnValue = kIOReturnSuccess;
-
- ioReturnValue = (*queue)->addElement(queue, cookie, 0);
- if ( ioReturnValue == kIOReturnSuccess )
- {
- printf("Registered pollElement: %ld\n", (long)cookie );
- }
- else
- {
- printf("Failed to add poll element: %ld\n", (long)cookie );
- }
-}
-
-/*
- * Class: net_java_games_input_OSXEnvironmentPlugin
- * Method: deregisterDeviceElement
- * Signature: (JJ)V
- */
-JNIEXPORT void JNICALL Java_net_java_games_input_OSXEnvironmentPlugin_deregisterDeviceElement
- (JNIEnv * env, jobject obj, jlong lpQueue, jlong hidCookie)
-{
- IOHIDQueueInterface **queue = NULL;
- queue = (IOHIDQueueInterface **)(long)lpQueue;
-
- IOHIDElementCookie cookie = (IOHIDElementCookie)(long)hidCookie;
-
- IOReturn ioReturnValue = kIOReturnSuccess;
-
- ioReturnValue = (*queue)->removeElement(queue, cookie );
- if ( ioReturnValue == kIOReturnSuccess )
- {
- printf("Removed pollElement: %ld\n", (long)cookie );
- }
- else
- {
- printf("Failed to remove poll element: %ld\n", (long)cookie );
- }
-}
-
-
-
diff --git a/plugins/OSX/src/native/macosxutil.c b/plugins/OSX/src/native/macosxutil.c
new file mode 100644
index 0000000..81b5cc6
--- /dev/null
+++ b/plugins/OSX/src/native/macosxutil.c
@@ -0,0 +1,197 @@
+/*
+ * %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 <CoreServices/CoreServices.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <jni.h>
+#include "util.h"
+#include "macosxutil.h"
+
+typedef struct {
+ JNIEnv *env;
+ jobject map;
+} dict_context_t;
+
+typedef struct {
+ JNIEnv *env;
+ jobjectArray array;
+ jsize index;
+} array_context_t;
+
+static jobject createObjectFromCFObject(JNIEnv *env, CFTypeRef cfobject);
+
+static jstring createStringFromCFString(JNIEnv *env, CFStringRef cfstring) {
+ CFIndex unicode_length = CFStringGetLength(cfstring);
+ CFIndex utf8_length = CFStringGetMaximumSizeForEncoding(unicode_length, kCFStringEncodingUTF8);
+ // Allocate buffer large enough, plus \0 terminator
+ char *buffer = (char *)malloc(utf8_length + 1);
+ if (buffer == NULL)
+ return NULL;
+ Boolean result = CFStringGetCString(cfstring, buffer, utf8_length + 1, kCFStringEncodingUTF8);
+ if (!result) {
+ free(buffer);
+ return NULL;
+ }
+ jstring str = (*env)->NewStringUTF(env, buffer);
+ free(buffer);
+ return str;
+}
+
+static jobject createDoubleObjectFromCFNumber(JNIEnv *env, CFNumberRef cfnumber) {
+ double value;
+ Boolean result = CFNumberGetValue(cfnumber, kCFNumberDoubleType, &value);
+ if (!result)
+ return NULL;
+ return newJObject(env, "java/lang/Double", "(D)V", (jdouble)value);
+}
+
+static jobject createLongObjectFromCFNumber(JNIEnv *env, CFNumberRef cfnumber) {
+ SInt64 value;
+ Boolean result = CFNumberGetValue(cfnumber, kCFNumberSInt64Type, &value);
+ if (!result)
+ return NULL;
+ return newJObject(env, "java/lang/Long", "(J)V", (jlong)value);
+}
+
+static jobject createNumberFromCFNumber(JNIEnv *env, CFNumberRef cfnumber) {
+ CFNumberType number_type = CFNumberGetType(cfnumber);
+ switch (number_type) {
+ case kCFNumberSInt8Type:
+ case kCFNumberSInt16Type:
+ case kCFNumberSInt32Type:
+ case kCFNumberSInt64Type:
+ case kCFNumberCharType:
+ case kCFNumberShortType:
+ case kCFNumberIntType:
+ case kCFNumberLongType:
+ case kCFNumberLongLongType:
+ case kCFNumberCFIndexType:
+ return createLongObjectFromCFNumber(env, cfnumber);
+ case kCFNumberFloat32Type:
+ case kCFNumberFloat64Type:
+ case kCFNumberFloatType:
+ case kCFNumberDoubleType:
+ return createDoubleObjectFromCFNumber(env, cfnumber);
+ default:
+ return NULL;
+ }
+}
+
+static void createArrayEntries(const void *value, void *context) {
+ array_context_t *array_context = (array_context_t *)context;
+ jobject jval = createObjectFromCFObject(array_context->env, value);
+ (*array_context->env)->SetObjectArrayElement(array_context->env, array_context->array, array_context->index++, jval);
+ (*array_context->env)->DeleteLocalRef(array_context->env, jval);
+}
+
+static jobject createArrayFromCFArray(JNIEnv *env, CFArrayRef cfarray) {
+ jclass Object_class = (*env)->FindClass(env, "java/lang/Object");
+ if (Object_class == NULL)
+ return NULL;
+ CFIndex size = CFArrayGetCount(cfarray);
+ CFRange range = {0, size};
+ jobjectArray array = (*env)->NewObjectArray(env, size, Object_class, NULL);
+ array_context_t array_context;
+ array_context.env = env;
+ array_context.array = array;
+ array_context.index = 0;
+ CFArrayApplyFunction(cfarray, range, createArrayEntries, &array_context);
+ return array;
+}
+
+static jobject createObjectFromCFObject(JNIEnv *env, CFTypeRef cfobject) {
+ CFTypeID type_id = CFGetTypeID(cfobject);
+ if (type_id == CFDictionaryGetTypeID()) {
+ return createMapFromCFDictionary(env, cfobject);
+ } else if (type_id == CFArrayGetTypeID()) {
+ return createArrayFromCFArray(env, cfobject);
+ } else if (type_id == CFStringGetTypeID()) {
+ return createStringFromCFString(env, cfobject);
+ } else if (type_id == CFNumberGetTypeID()) {
+ return createNumberFromCFNumber(env, cfobject);
+ } else {
+ return NULL;
+ }
+}
+
+static void createMapKeys(const void *key, const void *value, void *context) {
+ dict_context_t *dict_context = (dict_context_t *)context;
+
+ jclass Map_class = (*dict_context->env)->GetObjectClass(dict_context->env, dict_context->map);
+ if (Map_class == NULL)
+ return;
+ jmethodID map_put = (*dict_context->env)->GetMethodID(dict_context->env, Map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+ if (map_put == NULL)
+ return;
+ jobject jkey = createObjectFromCFObject(dict_context->env, key);
+ jobject jvalue = createObjectFromCFObject(dict_context->env, value);
+ if (jkey == NULL || jvalue == NULL)
+ return;
+ (*dict_context->env)->CallObjectMethod(dict_context->env, dict_context->map, map_put, jkey, jvalue);
+ (*dict_context->env)->DeleteLocalRef(dict_context->env, jkey);
+ (*dict_context->env)->DeleteLocalRef(dict_context->env, jvalue);
+}
+
+jobject createMapFromCFDictionary(JNIEnv *env, CFDictionaryRef dict) {
+ jobject map = newJObject(env, "java/util/HashMap", "()V");
+ if (map == NULL)
+ return NULL;
+ dict_context_t dict_context;
+ dict_context.env = env;
+ dict_context.map = map;
+ CFDictionaryApplyFunction(dict, createMapKeys, &dict_context);
+ return map;
+}
+
+void copyEvent(JNIEnv *env, IOHIDEventStruct *event, jobject event_return) {
+ jclass OSXEvent_class = (*env)->GetObjectClass(env, event_return);
+ if (OSXEvent_class == NULL) {
+ return;
+ }
+
+ jmethodID OSXEvent_set = (*env)->GetMethodID(env, OSXEvent_class, "set", "(JJIJ)V");
+ if (OSXEvent_set == NULL) {
+ return;
+ }
+ Nanoseconds nanos = AbsoluteToNanoseconds(event->timestamp);
+ uint64_t nanos64= *((uint64_t *)&nanos);
+ (*env)->CallVoidMethod(env, event_return, OSXEvent_set, (jlong)event->type, (jlong)(intptr_t)event->elementCookie, (jint)event->value, (jlong)nanos64);
+}
diff --git a/plugins/OSX/src/native/macosxutil.h b/plugins/OSX/src/native/macosxutil.h
new file mode 100644
index 0000000..ed2722c
--- /dev/null
+++ b/plugins/OSX/src/native/macosxutil.h
@@ -0,0 +1,48 @@
+/*
+ * %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 <jni.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/hid/IOHIDLib.h>
+
+extern jobject createMapFromCFDictionary(JNIEnv *env, CFDictionaryRef dict);
+extern void copyEvent(JNIEnv *env, IOHIDEventStruct *event, jobject event_return);
diff --git a/plugins/OSX/src/native/net_java_games_input_OSXHIDDevice.c b/plugins/OSX/src/native/net_java_games_input_OSXHIDDevice.c
new file mode 100644
index 0000000..cef6701
--- /dev/null
+++ b/plugins/OSX/src/native/net_java_games_input_OSXHIDDevice.c
@@ -0,0 +1,118 @@
+/*
+ * %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 <IOKit/IOTypes.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/hid/IOHIDKeys.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include "net_java_games_input_OSXHIDDevice.h"
+#include "util.h"
+#include "macosxutil.h"
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDevice_nReleaseDevice(JNIEnv *env, jclass unused, jlong device_address, jlong interface_address) {
+ io_object_t hidDevice = (io_object_t)device_address;
+ IOHIDDeviceInterface **device_interface = (IOHIDDeviceInterface **)(intptr_t)interface_address;;
+ (*device_interface)->Release(device_interface);
+ IOObjectRelease(hidDevice);
+}
+
+JNIEXPORT jobject JNICALL Java_net_java_games_input_OSXHIDDevice_nGetDeviceProperties(JNIEnv *env, jclass unused, jlong device_address) {
+ io_object_t hidDevice = (io_object_t)device_address;
+ CFMutableDictionaryRef properties;
+
+ kern_return_t result = IORegistryEntryCreateCFProperties(hidDevice,
+ &properties,
+ kCFAllocatorDefault,
+ kNilOptions);
+ if (result != KERN_SUCCESS) {
+ throwIOException(env, "Failed to create properties for device (%ld)", result);
+ return NULL;
+ }
+ jobject map = createMapFromCFDictionary(env, properties);
+ CFRelease(properties);
+ return map;
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDevice_nOpen
+ (JNIEnv * env, jclass unused, jlong lpDevice) {
+ IOHIDDeviceInterface **hidDeviceInterface = (IOHIDDeviceInterface **)(intptr_t)lpDevice;
+ IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, 0);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Device open failed: %d", ioReturnValue);
+ }
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDevice_nClose
+ (JNIEnv * env, jclass unused, jlong lpDevice) {
+ IOHIDDeviceInterface **hidDeviceInterface = (IOHIDDeviceInterface **)(intptr_t)lpDevice;
+ IOReturn ioReturnValue = (*hidDeviceInterface)->close(hidDeviceInterface);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Device close failed: %d", ioReturnValue);
+ }
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDevice_nGetElementValue
+ (JNIEnv * env, jclass unused, jlong lpDevice, jlong hidCookie, jobject event_return) {
+ IOHIDDeviceInterface **hidDeviceInterface = (IOHIDDeviceInterface **)(intptr_t)lpDevice;
+ IOHIDElementCookie cookie = (IOHIDElementCookie)(intptr_t)hidCookie;
+ IOHIDEventStruct event;
+
+ IOReturn ioReturnValue = (*hidDeviceInterface)->getElementValue(hidDeviceInterface, cookie, &event);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Device getElementValue failed: %d", ioReturnValue);
+ return;
+ }
+ copyEvent(env, &event, event_return);
+ if (event.longValue != NULL) {
+ free(event.longValue);
+ }
+}
+
+JNIEXPORT jlong JNICALL Java_net_java_games_input_OSXHIDDevice_nCreateQueue(JNIEnv *env, jclass unused, jlong device_address) {
+ IOHIDDeviceInterface **hidDeviceInterface = (IOHIDDeviceInterface **)(intptr_t)device_address;
+ IOHIDQueueInterface **queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface);
+
+ if (queue == NULL) {
+ throwIOException(env, "Could not allocate queue");
+ return 0;
+ }
+ return (jlong)(intptr_t)queue;
+}
diff --git a/plugins/OSX/src/native/net_java_games_input_OSXHIDDeviceIterator.c b/plugins/OSX/src/native/net_java_games_input_OSXHIDDeviceIterator.c
new file mode 100644
index 0000000..e76363f
--- /dev/null
+++ b/plugins/OSX/src/native/net_java_games_input_OSXHIDDeviceIterator.c
@@ -0,0 +1,143 @@
+/*
+ * %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 <IOKit/IOTypes.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/hid/IOHIDKeys.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include "net_java_games_input_OSXHIDDeviceIterator.h"
+#include "util.h"
+
+JNIEXPORT jlong JNICALL Java_net_java_games_input_OSXHIDDeviceIterator_nCreateIterator(JNIEnv *env, jclass unused) {
+ io_iterator_t hidObjectIterator;
+ // Set up a matching dictionary to search the I/O Registry by class
+ // name for all HID class devices
+ //
+ CFMutableDictionaryRef hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
+
+ // Now search I/O Registry for matching devices.
+ // IOServiceGetMatchingServices consumes a reference to the dictionary so we don't have to release it
+ IOReturn ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator);
+
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Failed to create iterator (%ld)\n", ioReturnValue);
+ return 0;
+ }
+
+ if (hidObjectIterator == IO_OBJECT_NULL) {
+ throwIOException(env, "Failed to create iterator\n");
+ return 0;
+ }
+ return (jlong)hidObjectIterator;
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDDeviceIterator_nReleaseIterator(JNIEnv *env, jclass unused, jlong address) {
+ io_iterator_t iterator = (io_iterator_t)address;
+ IOObjectRelease(iterator);
+}
+
+static IOHIDDeviceInterface **createHIDDevice(JNIEnv *env, io_object_t hidDevice) {
+// io_name_t className;
+ IOHIDDeviceInterface **hidDeviceInterface;
+ IOCFPlugInInterface **plugInInterface;
+ SInt32 score;
+
+/* ioReturnValue = IOObjectGetClass(hidDevice, className);
+ if (ioReturnValue != kIOReturnSuccess) {
+ printfJava(env, "Failed to get IOObject class name.");
+ }
+
+ printfJava(env, "Found device type [%s]\n", className);
+ */
+ IOReturn ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice,
+ kIOHIDDeviceUserClientTypeID,
+ kIOCFPlugInInterfaceID,
+ &plugInInterface,
+ &score);
+
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Couldn't create plugin for device interface (%ld)\n", ioReturnValue);
+ return NULL;
+ }
+ //Call a method of the intermediate plug-in to create the device
+ //interface
+ //
+ HRESULT plugInResult = (*plugInInterface)->QueryInterface(plugInInterface,
+ CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
+ (LPVOID)&hidDeviceInterface);
+ (*plugInInterface)->Release(plugInInterface);
+ if (plugInResult != S_OK) {
+ throwIOException(env, "Couldn't create HID class device interface (%ld)\n", plugInResult);
+ return NULL;
+ }
+ return hidDeviceInterface;
+}
+
+JNIEXPORT jobject JNICALL Java_net_java_games_input_OSXHIDDeviceIterator_nNext(JNIEnv *env, jclass unused, jlong address) {
+ io_iterator_t iterator = (io_iterator_t)address;
+ io_object_t hidDevice;
+// io_string_t path;
+// kern_return_t result;
+
+ hidDevice = IOIteratorNext(iterator);
+ if (hidDevice == MACH_PORT_NULL)
+ return NULL;
+/* IOResult result = IORegistryEntryGetPath(hidDevice, kIOServicePlane, path);
+
+ if (result != KERN_SUCCESS) {
+ IOObjectRelease(hidDevice);
+ throwIOException("Failed to get device path (%ld)\n", result);
+ return NULL;
+ }
+*/
+ IOHIDDeviceInterface **device_interface = createHIDDevice(env, hidDevice);
+ if (device_interface == NULL) {
+ IOObjectRelease(hidDevice);
+ return NULL;
+ }
+ jobject device_object = newJObject(env, "net/java/games/input/OSXHIDDevice", "(JJ)V", (jlong)hidDevice, (jlong)(intptr_t)device_interface);
+ if (device_object == NULL) {
+ (*device_interface)->Release(device_interface);
+ IOObjectRelease(hidDevice);
+ return NULL;
+ }
+ return device_object;
+}
diff --git a/plugins/OSX/src/native/net_java_games_input_OSXHIDQueue.c b/plugins/OSX/src/native/net_java_games_input_OSXHIDQueue.c
new file mode 100644
index 0000000..12dbd0a
--- /dev/null
+++ b/plugins/OSX/src/native/net_java_games_input_OSXHIDQueue.c
@@ -0,0 +1,135 @@
+/*
+ * %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 <IOKit/IOTypes.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/hid/IOHIDKeys.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include "net_java_games_input_OSXHIDQueue.h"
+#include "util.h"
+#include "macosxutil.h"
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nOpen(JNIEnv *env, jclass unused, jlong address, jint queue_depth) {
+ IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address;
+ IOReturn ioReturnValue = (*queue)->create(queue, 0, queue_depth);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Queue open failed: %d\n", ioReturnValue);
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nStart(JNIEnv *env, jclass unused, jlong address) {
+ IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address;
+ IOReturn ioReturnValue = (*queue)->start(queue);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Queue start failed: %d\n", ioReturnValue);
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nStop(JNIEnv *env, jclass unused, jlong address) {
+ IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address;
+ IOReturn ioReturnValue = (*queue)->stop(queue);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Queue stop failed: %d\n", ioReturnValue);
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nClose(JNIEnv *env, jclass unused, jlong address) {
+ IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address;
+ IOReturn ioReturnValue = (*queue)->dispose(queue);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Queue dispose failed: %d\n", ioReturnValue);
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nReleaseQueue(JNIEnv *env, jclass unused, jlong address) {
+ IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address;
+ IOReturn ioReturnValue = (*queue)->Release(queue);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Queue Release failed: %d\n", ioReturnValue);
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nAddElement(JNIEnv *env, jclass unused, jlong address, jlong cookie_address) {
+ IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address;
+ IOHIDElementCookie cookie = (IOHIDElementCookie)(intptr_t)cookie_address;
+
+ IOReturn ioReturnValue = (*queue)->addElement(queue, cookie, 0);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Queue addElement failed: %d\n", ioReturnValue);
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_net_java_games_input_OSXHIDQueue_nRemoveElement(JNIEnv *env, jclass unused, jlong address, jlong cookie_address) {
+ IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address;
+ IOHIDElementCookie cookie = (IOHIDElementCookie)(intptr_t)cookie_address;
+
+ IOReturn ioReturnValue = (*queue)->removeElement(queue, cookie);
+ if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Queue removeElement failed: %d\n", ioReturnValue);
+ return;
+ }
+}
+
+
+JNIEXPORT jboolean JNICALL Java_net_java_games_input_OSXHIDQueue_nGetNextEvent(JNIEnv *env, jclass unused, jlong address, jobject event_return) {
+ IOHIDQueueInterface **queue = (IOHIDQueueInterface **)(intptr_t)address;
+ IOHIDEventStruct event;
+
+ AbsoluteTime zeroTime = {0, 0};
+ IOReturn ioReturnValue = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
+ if (ioReturnValue == kIOReturnUnderrun) {
+ return JNI_FALSE;
+ } else if (ioReturnValue != kIOReturnSuccess) {
+ throwIOException(env, "Queue getNextEvent failed: %d\n", ioReturnValue);
+ return JNI_FALSE;
+ }
+ copyEvent(env, &event, event_return);
+ if (event.longValue != NULL) {
+ free(event.longValue);
+ }
+ return JNI_TRUE;
+}