diff options
Diffstat (limited to 'plugins/OSX/src/native')
-rw-r--r-- | plugins/OSX/src/native/build.xml | 80 | ||||
-rw-r--r-- | plugins/OSX/src/native/jinputjnilib.c | 839 | ||||
-rw-r--r-- | plugins/OSX/src/native/macosxutil.c | 197 | ||||
-rw-r--r-- | plugins/OSX/src/native/macosxutil.h | 48 | ||||
-rw-r--r-- | plugins/OSX/src/native/net_java_games_input_OSXHIDDevice.c | 118 | ||||
-rw-r--r-- | plugins/OSX/src/native/net_java_games_input_OSXHIDDeviceIterator.c | 143 | ||||
-rw-r--r-- | plugins/OSX/src/native/net_java_games_input_OSXHIDQueue.c | 135 |
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; +} |