From: Aric Stewart Subject: [2/2]Remove the old OS/X Joystick driver code in favor of the new stuff Message-Id: <5527E45E.9060101@codeweavers.com> Date: Fri, 10 Apr 2015 09:55:26 -0500 --- dlls/dinput/Makefile.in | 1 - dlls/dinput/dinput_main.c | 1 - dlls/dinput/dinput_private.h | 1 - dlls/dinput/joystick_osx.c | 1610 ------------------------------- dlls/winejoystick.drv/Makefile.in | 4 +- dlls/winejoystick.drv/joystick_driver.c | 2 - dlls/winejoystick.drv/joystick_osx.c | 753 --------------- 7 files changed, 1 insertion(+), 2371 deletions(-) delete mode 100644 dlls/dinput/joystick_osx.c delete mode 100644 dlls/winejoystick.drv/joystick_osx.c diff --git a/dlls/dinput/Makefile.in b/dlls/dinput/Makefile.in index 676eb55..bb79fa5 100644 --- a/dlls/dinput/Makefile.in +++ b/dlls/dinput/Makefile.in @@ -13,7 +13,6 @@ C_SRCS = \ joystick_driver.c \ joystick_linux.c \ joystick_linuxinput.c \ - joystick_osx.c \ keyboard.c \ mouse.c diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index beb1072..09f6526 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -90,7 +90,6 @@ static const struct dinput_device *dinput_devices[] = &keyboard_device, &joystick_linuxinput_device, &joystick_linux_device, - &joystick_osx_device, &joystick_driver_device }; #define NB_DINPUT_DEVICES (sizeof(dinput_devices)/sizeof(dinput_devices[0])) diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h index 7dfb9d7..cc9a085 100644 --- a/dlls/dinput/dinput_private.h +++ b/dlls/dinput/dinput_private.h @@ -61,7 +61,6 @@ extern const struct dinput_device keyboard_device DECLSPEC_HIDDEN; extern const struct dinput_device joystick_driver_device DECLSPEC_HIDDEN; extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN; extern const struct dinput_device joystick_linuxinput_device DECLSPEC_HIDDEN; -extern const struct dinput_device joystick_osx_device DECLSPEC_HIDDEN; extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8W) DECLSPEC_HIDDEN; typedef int (*DI_EVENT_PROC)(LPDIRECTINPUTDEVICE8A, WPARAM, LPARAM); diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c deleted file mode 100644 index 6a8926d..0000000 --- a/dlls/dinput/joystick_osx.c +++ /dev/null @@ -1,1610 +0,0 @@ -/* DirectInput Joystick device for Mac OS/X - * - * Copyright 1998 Marcus Meissner - * Copyright 1998,1999 Lionel Ulmer - * Copyright 2000-2001 TransGaming Technologies Inc. - * Copyright 2009 CodeWeavers, Aric Stewart - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#if defined(HAVE_IOKIT_HID_IOHIDLIB_H) -#define DWORD UInt32 -#define LPDWORD UInt32* -#define LONG SInt32 -#define LPLONG SInt32* -#define E_PENDING __carbon_E_PENDING -#define ULONG __carbon_ULONG -#define E_INVALIDARG __carbon_E_INVALIDARG -#define E_OUTOFMEMORY __carbon_E_OUTOFMEMORY -#define E_HANDLE __carbon_E_HANDLE -#define E_ACCESSDENIED __carbon_E_ACCESSDENIED -#define E_UNEXPECTED __carbon_E_UNEXPECTED -#define E_FAIL __carbon_E_FAIL -#define E_ABORT __carbon_E_ABORT -#define E_POINTER __carbon_E_POINTER -#define E_NOINTERFACE __carbon_E_NOINTERFACE -#define E_NOTIMPL __carbon_E_NOTIMPL -#define S_FALSE __carbon_S_FALSE -#define S_OK __carbon_S_OK -#define HRESULT_FACILITY __carbon_HRESULT_FACILITY -#define IS_ERROR __carbon_IS_ERROR -#define FAILED __carbon_FAILED -#define SUCCEEDED __carbon_SUCCEEDED -#define MAKE_HRESULT __carbon_MAKE_HRESULT -#define HRESULT __carbon_HRESULT -#define STDMETHODCALLTYPE __carbon_STDMETHODCALLTYPE -#include -#include -#include -#undef ULONG -#undef E_INVALIDARG -#undef E_OUTOFMEMORY -#undef E_HANDLE -#undef E_ACCESSDENIED -#undef E_UNEXPECTED -#undef E_FAIL -#undef E_ABORT -#undef E_POINTER -#undef E_NOINTERFACE -#undef E_NOTIMPL -#undef S_FALSE -#undef S_OK -#undef HRESULT_FACILITY -#undef IS_ERROR -#undef FAILED -#undef SUCCEEDED -#undef MAKE_HRESULT -#undef HRESULT -#undef STDMETHODCALLTYPE -#undef DWORD -#undef LPDWORD -#undef LONG -#undef LPLONG -#undef E_PENDING -#endif /* HAVE_IOKIT_HID_IOHIDLIB_H */ - -#include "wine/debug.h" -#include "wine/unicode.h" -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "winreg.h" -#include "dinput.h" - -#include "dinput_private.h" -#include "device_private.h" -#include "joystick_private.h" - -#ifdef HAVE_IOHIDMANAGERCREATE - -WINE_DEFAULT_DEBUG_CHANNEL(dinput); - -static CFMutableArrayRef device_main_elements = NULL; - -typedef struct JoystickImpl JoystickImpl; -static const IDirectInputDevice8AVtbl JoystickAvt; -static const IDirectInputDevice8WVtbl JoystickWvt; - -struct JoystickImpl -{ - struct JoystickGenericImpl generic; - - /* osx private */ - int id; - CFArrayRef elements; - ObjProps **propmap; - FFDeviceObjectReference ff; - struct list effects; -}; - -static inline JoystickImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface) -{ - return CONTAINING_RECORD(CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8A_iface), - JoystickGenericImpl, base), JoystickImpl, generic); -} -static inline JoystickImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface) -{ - return CONTAINING_RECORD(CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8W_iface), - JoystickGenericImpl, base), JoystickImpl, generic); -} - -typedef struct _EffectImpl { - IDirectInputEffect IDirectInputEffect_iface; - LONG ref; - - JoystickImpl *device; - FFEffectObjectReference effect; - GUID guid; - - struct list entry; -} EffectImpl; - -static EffectImpl *impl_from_IDirectInputEffect(IDirectInputEffect *iface) -{ - return CONTAINING_RECORD(iface, EffectImpl, IDirectInputEffect_iface); -} - -static const IDirectInputEffectVtbl EffectVtbl; - -static const GUID DInput_Wine_OsX_Joystick_GUID = { /* 59CAD8F6-E617-41E2-8EB7-47B23EEEDC5A */ - 0x59CAD8F6, 0xE617, 0x41E2, {0x8E, 0xB7, 0x47, 0xB2, 0x3E, 0xEE, 0xDC, 0x5A} -}; - -static HRESULT osx_to_win32_hresult(HRESULT in) -{ - /* OSX returns 16-bit COM runtime errors, which we should - * convert to win32 */ - switch(in){ - case 0x80000001: - return E_NOTIMPL; - case 0x80000002: - return E_OUTOFMEMORY; - case 0x80000003: - return E_INVALIDARG; - case 0x80000004: - return E_NOINTERFACE; - case 0x80000005: - return E_POINTER; - case 0x80000006: - return E_HANDLE; - case 0x80000007: - return E_ABORT; - case 0x80000008: - return E_FAIL; - case 0x80000009: - return E_ACCESSDENIED; - case 0x8000FFFF: - return E_UNEXPECTED; - } - return in; -} - -static void CFSetApplierFunctionCopyToCFArray(const void *value, void *context) -{ - CFArrayAppendValue( ( CFMutableArrayRef ) context, value ); -} - -static const char* debugstr_cf(CFTypeRef t) -{ - CFStringRef s; - const char* ret; - - if (!t) return "(null)"; - - if (CFGetTypeID(t) == CFStringGetTypeID()) - s = t; - else - s = CFCopyDescription(t); - ret = CFStringGetCStringPtr(s, kCFStringEncodingUTF8); - if (ret) ret = debugstr_a(ret); - if (!ret) - { - const UniChar* u = CFStringGetCharactersPtr(s); - if (u) - ret = debugstr_wn((const WCHAR*)u, CFStringGetLength(s)); - } - if (!ret) - { - UniChar buf[200]; - int len = min(CFStringGetLength(s), sizeof(buf)/sizeof(buf[0])); - CFStringGetCharacters(s, CFRangeMake(0, len), buf); - ret = debugstr_wn(buf, len); - } - if (s != t) CFRelease(s); - return ret; -} - -static const char* debugstr_device(IOHIDDeviceRef device) -{ - return wine_dbg_sprintf("", device, - debugstr_cf(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)))); -} - -static const char* debugstr_element(IOHIDElementRef element) -{ - return wine_dbg_sprintf("", element, - IOHIDElementGetType(element), IOHIDElementGetUsagePage(element), - IOHIDElementGetUsage(element), IOHIDElementGetDevice(element)); -} - -static IOHIDDeviceRef get_device_ref(int id) -{ - IOHIDElementRef device_main_element; - IOHIDDeviceRef hid_device; - - TRACE("id %d\n", id); - - if (!device_main_elements || id >= CFArrayGetCount(device_main_elements)) - return 0; - - device_main_element = (IOHIDElementRef)CFArrayGetValueAtIndex(device_main_elements, id); - if (!device_main_element) - { - ERR("Invalid Element requested %i\n",id); - return 0; - } - - hid_device = IOHIDElementGetDevice(device_main_element); - if (!hid_device) - { - ERR("Invalid Device requested %i\n",id); - return 0; - } - - TRACE("-> %s\n", debugstr_device(hid_device)); - return hid_device; -} - -static HRESULT get_ff(IOHIDDeviceRef device, FFDeviceObjectReference *ret) -{ - io_service_t service; - CFMutableDictionaryRef matching; - CFTypeRef location_id; - HRESULT hr; - - TRACE("device %s\n", debugstr_device(device)); - - matching = IOServiceMatching(kIOHIDDeviceKey); - if(!matching){ - WARN("IOServiceMatching failed, force feedback disabled\n"); - return DIERR_DEVICENOTREG; - } - - location_id = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDLocationIDKey)); - if(!location_id){ - CFRelease(matching); - WARN("IOHIDDeviceGetProperty failed, force feedback disabled\n"); - return DIERR_DEVICENOTREG; - } - - CFDictionaryAddValue(matching, CFSTR(kIOHIDLocationIDKey), location_id); - - service = IOServiceGetMatchingService(kIOMasterPortDefault, matching); - - if (ret) - hr = osx_to_win32_hresult(FFCreateDevice(service, ret)); - else - hr = FFIsForceFeedback(service) == FF_OK ? S_OK : S_FALSE; - - IOObjectRelease(service); - TRACE("-> hr 0x%08x *ret %p\n", hr, ret ? *ret : NULL); - return hr; -} - -static CFMutableDictionaryRef create_osx_device_match(int usage) -{ - CFMutableDictionaryRef result; - - TRACE("usage %d\n", usage); - - result = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); - - if ( result ) - { - int number = kHIDPage_GenericDesktop; - CFNumberRef page = CFNumberCreate( kCFAllocatorDefault, - kCFNumberIntType, &number); - - if (page) - { - CFNumberRef cf_usage; - - CFDictionarySetValue( result, CFSTR( kIOHIDDeviceUsagePageKey ), page ); - CFRelease( page ); - - cf_usage = CFNumberCreate( kCFAllocatorDefault, - kCFNumberIntType, &usage); - if (cf_usage) - { - CFDictionarySetValue( result, CFSTR( kIOHIDDeviceUsageKey ), cf_usage ); - CFRelease( cf_usage ); - } - else - { - ERR("CFNumberCreate() failed.\n"); - CFRelease(result); - return NULL; - } - } - else - { - ERR("CFNumberCreate failed.\n"); - CFRelease(result); - return NULL; - } - } - else - { - ERR("CFDictionaryCreateMutable failed.\n"); - return NULL; - } - - return result; -} - -static CFIndex find_top_level(IOHIDDeviceRef hid_device, CFMutableArrayRef main_elements) -{ - CFArrayRef elements; - CFIndex total = 0; - - TRACE("hid_device %s\n", debugstr_device(hid_device)); - - if (!hid_device) - return 0; - - elements = IOHIDDeviceCopyMatchingElements(hid_device, NULL, 0); - - if (elements) - { - CFIndex idx, cnt = CFArrayGetCount(elements); - for (idx=0; idx total %d\n", (int)total); - return total; -} - -static void get_element_children(IOHIDElementRef element, CFMutableArrayRef all_children) -{ - CFIndex idx, cnt; - CFArrayRef element_children = IOHIDElementGetChildren(element); - - TRACE("element %s\n", debugstr_element(element)); - - cnt = CFArrayGetCount(element_children); - - /* Either add the element to the array or grab its children */ - for (idx=0; idx= len) - { - CFStringGetCString(str,name,length,kCFStringEncodingASCII); - return len; - } - else - return (len+1); - } - return 0; -} - -static CFComparisonResult button_usage_comparator(const void *val1, const void *val2, void *context) -{ - IOHIDElementRef element1 = (IOHIDElementRef)val1, element2 = (IOHIDElementRef)val2; - int usage1 = IOHIDElementGetUsage(element1), usage2 = IOHIDElementGetUsage(element2); - - if (usage1 < usage2) - return kCFCompareLessThan; - if (usage1 > usage2) - return kCFCompareGreaterThan; - return kCFCompareEqualTo; -} - -static void get_osx_device_elements(JoystickImpl *device, int axis_map[8]) -{ - IOHIDElementRef device_main_element; - CFMutableArrayRef elements; - DWORD sliders = 0; - - TRACE("device %p device->id %d\n", device, device->id); - - device->elements = NULL; - - if (!device_main_elements || device->id >= CFArrayGetCount(device_main_elements)) - return; - - device_main_element = (IOHIDElementRef)CFArrayGetValueAtIndex(device_main_elements, device->id); - TRACE("device_main_element %s\n", debugstr_element(device_main_element)); - if (!device_main_element) - return; - - elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - get_element_children(device_main_element, elements); - - if (elements) - { - CFIndex idx, cnt = CFArrayGetCount( elements ); - CFMutableArrayRef axes = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - CFMutableArrayRef buttons = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - CFMutableArrayRef povs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - - for ( idx = 0; idx < cnt; idx++ ) - { - IOHIDElementRef element = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elements, idx ); - int type = IOHIDElementGetType( element ); - - TRACE("element %s\n", debugstr_element(element)); - - switch(type) - { - case kIOHIDElementTypeInput_Button: - { - int usage_page = IOHIDElementGetUsagePage( element ); - TRACE("kIOHIDElementTypeInput_Button usage_page %d\n", usage_page); - if (usage_page != kHIDPage_Button) - { - /* avoid strange elements found on the 360 controller */ - continue; - } - - if (CFArrayGetCount(buttons) < 128) - CFArrayAppendValue(buttons, element); - break; - } - case kIOHIDElementTypeInput_Axis: - { - TRACE("kIOHIDElementTypeInput_Axis\n"); - CFArrayAppendValue(axes, element); - break; - } - case kIOHIDElementTypeInput_Misc: - { - uint32_t usage = IOHIDElementGetUsage( element ); - switch(usage) - { - case kHIDUsage_GD_Hatswitch: - { - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Hatswitch\n"); - CFArrayAppendValue(povs, element); - break; - } - case kHIDUsage_GD_Slider: - sliders ++; - if (sliders > 2) - break; - /* fallthrough, sliders are axis */ - case kHIDUsage_GD_X: - case kHIDUsage_GD_Y: - case kHIDUsage_GD_Z: - case kHIDUsage_GD_Rx: - case kHIDUsage_GD_Ry: - case kHIDUsage_GD_Rz: - { - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_* (%d)\n", usage); - axis_map[CFArrayGetCount(axes)]=usage; - CFArrayAppendValue(axes, element); - break; - } - default: - FIXME("kIOHIDElementTypeInput_Misc / Unhandled usage %i\n", usage); - } - break; - } - default: - FIXME("Unhandled type %i\n",type); - } - } - - /* Sort buttons into correct order */ - CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)), button_usage_comparator, NULL); - - device->generic.devcaps.dwAxes = CFArrayGetCount(axes); - device->generic.devcaps.dwButtons = CFArrayGetCount(buttons); - device->generic.devcaps.dwPOVs = CFArrayGetCount(povs); - - TRACE("axes %u povs %u buttons %u\n", device->generic.devcaps.dwAxes, device->generic.devcaps.dwPOVs, - device->generic.devcaps.dwButtons); - - /* build our element array in the order that dinput expects */ - CFArrayAppendArray(axes, povs, CFRangeMake(0, device->generic.devcaps.dwPOVs)); - CFArrayAppendArray(axes, buttons, CFRangeMake(0, device->generic.devcaps.dwButtons)); - device->elements = axes; - axes = NULL; - - CFRelease(povs); - CFRelease(buttons); - CFRelease(elements); - } - else - { - device->generic.devcaps.dwAxes = 0; - device->generic.devcaps.dwButtons = 0; - device->generic.devcaps.dwPOVs = 0; - } -} - -static void get_osx_device_elements_props(JoystickImpl *device) -{ - TRACE("device %p\n", device); - - if (device->elements) - { - CFIndex idx, cnt = CFArrayGetCount( device->elements ); - - for ( idx = 0; idx < cnt; idx++ ) - { - IOHIDElementRef element = ( IOHIDElementRef ) CFArrayGetValueAtIndex( device->elements, idx ); - - TRACE("element %s\n", debugstr_element(element)); - - device->generic.props[idx].lDevMin = IOHIDElementGetLogicalMin(element); - device->generic.props[idx].lDevMax = IOHIDElementGetLogicalMax(element); - device->generic.props[idx].lMin = 0; - device->generic.props[idx].lMax = 0xffff; - device->generic.props[idx].lDeadZone = 0; - device->generic.props[idx].lSaturation = 0; - } - } -} - -static void poll_osx_device_state(LPDIRECTINPUTDEVICE8A iface) -{ - JoystickImpl *device = impl_from_IDirectInputDevice8A(iface); - IOHIDElementRef device_main_element; - IOHIDDeviceRef hid_device; - - TRACE("device %p device->id %i\n", device, device->id); - - if (!device_main_elements || device->id >= CFArrayGetCount(device_main_elements)) - return; - - device_main_element = (IOHIDElementRef) CFArrayGetValueAtIndex(device_main_elements, device->id); - hid_device = IOHIDElementGetDevice(device_main_element); - TRACE("main element %s hid_device %s\n", debugstr_element(device_main_element), debugstr_device(hid_device)); - if (!hid_device) - return; - - if (device->elements) - { - int button_idx = 0; - int pov_idx = 0; - int slider_idx = 0; - int inst_id; - CFIndex idx, cnt = CFArrayGetCount( device->elements ); - - for ( idx = 0; idx < cnt; idx++ ) - { - IOHIDValueRef valueRef; - int val, oldVal, newVal; - IOHIDElementRef element = ( IOHIDElementRef ) CFArrayGetValueAtIndex( device->elements, idx ); - int type = IOHIDElementGetType( element ); - - TRACE("element %s\n", debugstr_element(element)); - - switch(type) - { - case kIOHIDElementTypeInput_Button: - TRACE("kIOHIDElementTypeInput_Button\n"); - if(button_idx < 128) - { - IOHIDDeviceGetValue(hid_device, element, &valueRef); - val = IOHIDValueGetIntegerValue(valueRef); - newVal = val ? 0x80 : 0x0; - oldVal = device->generic.js.rgbButtons[button_idx]; - device->generic.js.rgbButtons[button_idx] = newVal; - TRACE("valueRef %s val %d oldVal %d newVal %d\n", debugstr_cf(valueRef), val, oldVal, newVal); - if (oldVal != newVal) - { - inst_id = DIDFT_MAKEINSTANCE(button_idx) | DIDFT_PSHBUTTON; - queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); - } - button_idx ++; - } - break; - case kIOHIDElementTypeInput_Misc: - { - uint32_t usage = IOHIDElementGetUsage( element ); - switch(usage) - { - case kHIDUsage_GD_Hatswitch: - { - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Hatswitch\n"); - IOHIDDeviceGetValue(hid_device, element, &valueRef); - val = IOHIDValueGetIntegerValue(valueRef); - oldVal = device->generic.js.rgdwPOV[pov_idx]; - if (val >= 8) - newVal = -1; - else - newVal = val * 4500; - device->generic.js.rgdwPOV[pov_idx] = newVal; - TRACE("valueRef %s val %d oldVal %d newVal %d\n", debugstr_cf(valueRef), val, oldVal, newVal); - if (oldVal != newVal) - { - inst_id = DIDFT_MAKEINSTANCE(pov_idx) | DIDFT_POV; - queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); - } - pov_idx ++; - break; - } - case kHIDUsage_GD_X: - case kHIDUsage_GD_Y: - case kHIDUsage_GD_Z: - case kHIDUsage_GD_Rx: - case kHIDUsage_GD_Ry: - case kHIDUsage_GD_Rz: - case kHIDUsage_GD_Slider: - { - int wine_obj = -1; - - IOHIDDeviceGetValue(hid_device, element, &valueRef); - val = IOHIDValueGetIntegerValue(valueRef); - newVal = joystick_map_axis(&device->generic.props[idx], val); - switch (usage) - { - case kHIDUsage_GD_X: - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_X\n"); - wine_obj = 0; - oldVal = device->generic.js.lX; - device->generic.js.lX = newVal; - break; - case kHIDUsage_GD_Y: - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Y\n"); - wine_obj = 1; - oldVal = device->generic.js.lY; - device->generic.js.lY = newVal; - break; - case kHIDUsage_GD_Z: - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Z\n"); - wine_obj = 2; - oldVal = device->generic.js.lZ; - device->generic.js.lZ = newVal; - break; - case kHIDUsage_GD_Rx: - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Rx\n"); - wine_obj = 3; - oldVal = device->generic.js.lRx; - device->generic.js.lRx = newVal; - break; - case kHIDUsage_GD_Ry: - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Ry\n"); - wine_obj = 4; - oldVal = device->generic.js.lRy; - device->generic.js.lRy = newVal; - break; - case kHIDUsage_GD_Rz: - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Rz\n"); - wine_obj = 5; - oldVal = device->generic.js.lRz; - device->generic.js.lRz = newVal; - break; - case kHIDUsage_GD_Slider: - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Slider\n"); - wine_obj = 6 + slider_idx; - oldVal = device->generic.js.rglSlider[slider_idx]; - device->generic.js.rglSlider[slider_idx] = newVal; - slider_idx ++; - break; - } - TRACE("valueRef %s val %d oldVal %d newVal %d\n", debugstr_cf(valueRef), val, oldVal, newVal); - if ((wine_obj != -1) && - (oldVal != newVal)) - { - inst_id = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS; - queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); - } - - break; - } - default: - FIXME("kIOHIDElementTypeInput_Misc / unhandled usage %i\n", usage); - } - break; - } - default: - FIXME("Unhandled type %i\n",type); - } - } - } -} - -static INT find_joystick_devices(void) -{ - static INT joystick_devices_count = -1; - - if (joystick_devices_count != -1) return joystick_devices_count; - - joystick_devices_count = find_osx_devices(); - - return joystick_devices_count; -} - -static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id) -{ - TRACE("dwDevType %u dwFlags 0x%08x version 0x%04x id %d\n", dwDevType, dwFlags, version, id); - - if (id >= find_joystick_devices()) return E_FAIL; - - if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || - (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) - { - if (dwFlags & DIEDFL_FORCEFEEDBACK) { - IOHIDDeviceRef device = get_device_ref(id); - if(!device) - return S_FALSE; - if(get_ff(device, NULL) != S_OK) - return S_FALSE; - } - /* Return joystick */ - lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID; - lpddi->guidInstance.Data3 = id; - lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID; - /* we only support traditional joysticks for now */ - if (version >= 0x0800) - lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); - else - lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); - sprintf(lpddi->tszInstanceName, "Joystick %d", id); - - /* get the device name */ - get_osx_device_name(id, lpddi->tszProductName, MAX_PATH); - - lpddi->guidFFDriver = GUID_NULL; - return S_OK; - } - - return S_FALSE; -} - -static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id) -{ - char name[MAX_PATH]; - char friendly[32]; - - TRACE("dwDevType %u dwFlags 0x%08x version 0x%04x id %d\n", dwDevType, dwFlags, version, id); - - if (id >= find_joystick_devices()) return E_FAIL; - - if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || - (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) { - if (dwFlags & DIEDFL_FORCEFEEDBACK) { - IOHIDDeviceRef device = get_device_ref(id); - if(!device) - return S_FALSE; - if(get_ff(device, NULL) != S_OK) - return S_FALSE; - } - /* Return joystick */ - lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID; - lpddi->guidInstance.Data3 = id; - lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID; - /* we only support traditional joysticks for now */ - if (version >= 0x0800) - lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); - else - lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); - sprintf(friendly, "Joystick %d", id); - MultiByteToWideChar(CP_ACP, 0, friendly, -1, lpddi->tszInstanceName, MAX_PATH); - /* get the device name */ - get_osx_device_name(id, name, MAX_PATH); - - MultiByteToWideChar(CP_ACP, 0, name, -1, lpddi->tszProductName, MAX_PATH); - lpddi->guidFFDriver = GUID_NULL; - return S_OK; - } - - return S_FALSE; -} - -static const char *osx_ff_axis_name(UInt8 axis) -{ - static char ret[6]; - switch(axis){ - case FFJOFS_X: - return "FFJOFS_X"; - case FFJOFS_Y: - return "FFJOFS_Y"; - case FFJOFS_Z: - return "FFJOFS_Z"; - } - sprintf(ret, "%u", (unsigned int)axis); - return ret; -} - -static BOOL osx_axis_has_ff(FFCAPABILITIES *ffcaps, UInt8 axis) -{ - int i; - for(i = 0; i < ffcaps->numFfAxes; ++i) - if(ffcaps->ffAxes[i] == axis) - return TRUE; - return FALSE; -} - -static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput, - JoystickImpl **pdev, unsigned short index) -{ - DWORD i; - IOHIDDeviceRef device; - JoystickImpl* newDevice; - char name[MAX_PATH]; - HRESULT hr; - LPDIDATAFORMAT df = NULL; - int idx = 0; - int axis_map[8]; /* max axes */ - int slider_count = 0; - FFCAPABILITIES ffcaps; - - TRACE("%s %p %p %hu\n", debugstr_guid(rguid), dinput, pdev, index); - - newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl)); - if (newDevice == 0) { - WARN("out of memory\n"); - *pdev = 0; - return DIERR_OUTOFMEMORY; - } - - newDevice->id = index; - - newDevice->generic.guidInstance = DInput_Wine_OsX_Joystick_GUID; - newDevice->generic.guidInstance.Data3 = index; - newDevice->generic.guidProduct = DInput_Wine_OsX_Joystick_GUID; - newDevice->generic.joy_polldev = poll_osx_device_state; - - /* get the device name */ - get_osx_device_name(index, name, MAX_PATH); - TRACE("Name %s\n",name); - - /* copy the device name */ - newDevice->generic.name = HeapAlloc(GetProcessHeap(),0,strlen(name) + 1); - strcpy(newDevice->generic.name, name); - - list_init(&newDevice->effects); - device = get_device_ref(index); - if(get_ff(device, &newDevice->ff) == S_OK){ - newDevice->generic.devcaps.dwFlags |= DIDC_FORCEFEEDBACK; - - hr = FFDeviceGetForceFeedbackCapabilities(newDevice->ff, &ffcaps); - if(SUCCEEDED(hr)){ - TRACE("FF Capabilities:\n"); - TRACE("\tsupportedEffects: 0x%x\n", (unsigned int)ffcaps.supportedEffects); - TRACE("\temulatedEffects: 0x%x\n", (unsigned int)ffcaps.emulatedEffects); - TRACE("\tsubType: 0x%x\n", (unsigned int)ffcaps.subType); - TRACE("\tnumFfAxes: %u\n", (unsigned int)ffcaps.numFfAxes); - TRACE("\tffAxes: ["); - for(i = 0; i < ffcaps.numFfAxes; ++i){ - TRACE("%s", osx_ff_axis_name(ffcaps.ffAxes[i])); - if(i < ffcaps.numFfAxes - 1) - TRACE(", "); - } - TRACE("]\n"); - TRACE("\tstorageCapacity: %u\n", (unsigned int)ffcaps.storageCapacity); - TRACE("\tplaybackCapacity: %u\n", (unsigned int)ffcaps.playbackCapacity); - } - - hr = FFDeviceSendForceFeedbackCommand(newDevice->ff, FFSFFC_RESET); - if(FAILED(hr)) - WARN("FFDeviceSendForceFeedbackCommand(FFSFFC_RESET) failed: %08x\n", hr); - - hr = FFDeviceSendForceFeedbackCommand(newDevice->ff, FFSFFC_SETACTUATORSON); - if(FAILED(hr)) - WARN("FFDeviceSendForceFeedbackCommand(FFSFFC_SETACTUATORSON) failed: %08x\n", hr); - } - - memset(axis_map, 0, sizeof(axis_map)); - get_osx_device_elements(newDevice, axis_map); - - TRACE("%i axes %i buttons %i povs\n",newDevice->generic.devcaps.dwAxes,newDevice->generic.devcaps.dwButtons,newDevice->generic.devcaps.dwPOVs); - - if (newDevice->generic.devcaps.dwButtons > 128) - { - WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->generic.devcaps.dwButtons); - newDevice->generic.devcaps.dwButtons = 128; - } - - newDevice->generic.base.IDirectInputDevice8A_iface.lpVtbl = &JoystickAvt; - newDevice->generic.base.IDirectInputDevice8W_iface.lpVtbl = &JoystickWvt; - newDevice->generic.base.ref = 1; - newDevice->generic.base.dinput = dinput; - newDevice->generic.base.guid = *rguid; - InitializeCriticalSection(&newDevice->generic.base.crit); - newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit"); - - /* Create copy of default data format */ - if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED; - memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize); - - df->dwNumObjs = newDevice->generic.devcaps.dwAxes + newDevice->generic.devcaps.dwPOVs + newDevice->generic.devcaps.dwButtons; - if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED; - - for (i = 0; i < newDevice->generic.devcaps.dwAxes; i++) - { - int wine_obj = -1; - BOOL has_ff = FALSE; - switch (axis_map[i]) - { - case kHIDUsage_GD_X: - wine_obj = 0; - has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_X); - break; - case kHIDUsage_GD_Y: - wine_obj = 1; - has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_Y); - break; - case kHIDUsage_GD_Z: - wine_obj = 2; - has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_Z); - break; - case kHIDUsage_GD_Rx: - wine_obj = 3; - has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_RX); - break; - case kHIDUsage_GD_Ry: - wine_obj = 4; - has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_RY); - break; - case kHIDUsage_GD_Rz: - wine_obj = 5; - has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_RZ); - break; - case kHIDUsage_GD_Slider: - wine_obj = 6 + slider_count; - has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_SLIDER(slider_count)); - slider_count++; - break; - } - if (wine_obj < 0 ) continue; - - memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize); - df->rgodf[idx].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS; - if(has_ff) - df->rgodf[idx].dwFlags |= DIDOI_FFACTUATOR; - ++idx; - } - - for (i = 0; i < newDevice->generic.devcaps.dwPOVs; i++) - { - memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 8], df->dwObjSize); - df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_POV; - } - - for (i = 0; i < newDevice->generic.devcaps.dwButtons; i++) - { - memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize); - df->rgodf[idx ].pguid = &GUID_Button; - df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON; - } - newDevice->generic.base.data_format.wine_df = df; - - /* initialize default properties */ - get_osx_device_elements_props(newDevice); - - IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface); - - EnterCriticalSection(&dinput->crit); - list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry); - LeaveCriticalSection(&dinput->crit); - - newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps); - newDevice->generic.devcaps.dwFlags |= DIDC_ATTACHED; - if (newDevice->generic.base.dinput->dwVersion >= 0x0800) - newDevice->generic.devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); - else - newDevice->generic.devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); - newDevice->generic.devcaps.dwFFSamplePeriod = 0; - newDevice->generic.devcaps.dwFFMinTimeResolution = 0; - newDevice->generic.devcaps.dwFirmwareRevision = 0; - newDevice->generic.devcaps.dwHardwareRevision = 0; - newDevice->generic.devcaps.dwFFDriverVersion = 0; - - if (TRACE_ON(dinput)) { - TRACE("allocated device %p\n", newDevice); - _dump_DIDATAFORMAT(newDevice->generic.base.data_format.wine_df); - _dump_DIDEVCAPS(&newDevice->generic.devcaps); - } - - *pdev = newDevice; - - return DI_OK; - -FAILED: - hr = DIERR_OUTOFMEMORY; - if (newDevice->ff) FFReleaseDevice(newDevice->ff); - if (newDevice->elements) CFRelease(newDevice->elements); - if (df) HeapFree(GetProcessHeap(), 0, df->rgodf); - HeapFree(GetProcessHeap(), 0, df); - release_DataFormat(&newDevice->generic.base.data_format); - HeapFree(GetProcessHeap(),0,newDevice->generic.name); - HeapFree(GetProcessHeap(),0,newDevice); - *pdev = 0; - - return hr; -} - -/****************************************************************************** - * get_joystick_index : Get the joystick index from a given GUID - */ -static unsigned short get_joystick_index(REFGUID guid) -{ - GUID wine_joystick = DInput_Wine_OsX_Joystick_GUID; - GUID dev_guid = *guid; - - wine_joystick.Data3 = 0; - dev_guid.Data3 = 0; - - /* for the standard joystick GUID use index 0 */ - if(IsEqualGUID(&GUID_Joystick,guid)) return 0; - - /* for the wine joystick GUIDs use the index stored in Data3 */ - if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3; - - return 0xffff; -} - -static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode) -{ - unsigned short index; - int joystick_devices_count; - - TRACE("%p %s %s %p %i\n", dinput, debugstr_guid(rguid), debugstr_guid(riid), pdev, unicode); - *pdev = NULL; - - if ((joystick_devices_count = find_joystick_devices()) == 0) - return DIERR_DEVICENOTREG; - - if ((index = get_joystick_index(rguid)) < 0xffff && - joystick_devices_count && index < joystick_devices_count) - { - JoystickImpl *This; - HRESULT hr; - - if (riid == NULL) - ;/* nothing */ - else if (IsEqualGUID(&IID_IDirectInputDeviceA, riid) || - IsEqualGUID(&IID_IDirectInputDevice2A, riid) || - IsEqualGUID(&IID_IDirectInputDevice7A, riid) || - IsEqualGUID(&IID_IDirectInputDevice8A, riid)) - { - unicode = 0; - } - else if (IsEqualGUID(&IID_IDirectInputDeviceW, riid) || - IsEqualGUID(&IID_IDirectInputDevice2W, riid) || - IsEqualGUID(&IID_IDirectInputDevice7W, riid) || - IsEqualGUID(&IID_IDirectInputDevice8W, riid)) - { - unicode = 1; - } - else - { - WARN("no interface\n"); - return DIERR_NOINTERFACE; - } - - hr = alloc_device(rguid, dinput, &This, index); - if (!This) return hr; - - if (unicode) - *pdev = &This->generic.base.IDirectInputDevice8W_iface; - else - *pdev = &This->generic.base.IDirectInputDevice8A_iface; - return hr; - } - - return DIERR_DEVICENOTREG; -} - -static HRESULT osx_set_autocenter(JoystickImpl *This, - const DIPROPDWORD *header) -{ - UInt32 v; - HRESULT hr; - if(!This->ff) - return DIERR_UNSUPPORTED; - v = header->dwData; - hr = osx_to_win32_hresult(FFDeviceSetForceFeedbackProperty(This->ff, FFPROP_AUTOCENTER, &v)); - TRACE("returning: %08x\n", hr); - return hr; -} - -static HRESULT osx_set_ffgain(JoystickImpl *This, const DIPROPDWORD *header) -{ - UInt32 v; - HRESULT hr; - if(!This->ff) - return DIERR_UNSUPPORTED; - v = header->dwData; - hr = osx_to_win32_hresult(FFDeviceSetForceFeedbackProperty(This->ff, FFPROP_FFGAIN, &v)); - TRACE("returning: %08x\n", hr); - return hr; -} - -static HRESULT WINAPI JoystickWImpl_SetProperty(IDirectInputDevice8W *iface, - const GUID *prop, const DIPROPHEADER *header) -{ - JoystickImpl *This = impl_from_IDirectInputDevice8W(iface); - - TRACE("%p %s %p\n", This, debugstr_guid(prop), header); - - switch(LOWORD(prop)) - { - case (DWORD_PTR)DIPROP_AUTOCENTER: - return osx_set_autocenter(This, (const DIPROPDWORD *)header); - case (DWORD_PTR)DIPROP_FFGAIN: - return osx_set_ffgain(This, (const DIPROPDWORD *)header); - } - - return JoystickWGenericImpl_SetProperty(iface, prop, header); -} - -static HRESULT WINAPI JoystickAImpl_SetProperty(IDirectInputDevice8A *iface, - const GUID *prop, const DIPROPHEADER *header) -{ - JoystickImpl *This = impl_from_IDirectInputDevice8A(iface); - - TRACE("%p %s %p\n", This, debugstr_guid(prop), header); - - switch(LOWORD(prop)) - { - case (DWORD_PTR)DIPROP_AUTOCENTER: - return osx_set_autocenter(This, (const DIPROPDWORD *)header); - case (DWORD_PTR)DIPROP_FFGAIN: - return osx_set_ffgain(This, (const DIPROPDWORD *)header); - } - - return JoystickAGenericImpl_SetProperty(iface, prop, header); -} - -static CFUUIDRef effect_win_to_mac(const GUID *effect) -{ -#define DO_MAP(X) \ - if(IsEqualGUID(&GUID_##X, effect)) \ - return kFFEffectType_##X##_ID; - DO_MAP(ConstantForce) - DO_MAP(RampForce) - DO_MAP(Square) - DO_MAP(Sine) - DO_MAP(Triangle) - DO_MAP(SawtoothUp) - DO_MAP(SawtoothDown) - DO_MAP(Spring) - DO_MAP(Damper) - DO_MAP(Inertia) - DO_MAP(Friction) - DO_MAP(CustomForce) -#undef DO_MAP - WARN("Unknown effect GUID! %s\n", debugstr_guid(effect)); - return 0; -} - -static HRESULT WINAPI JoystickWImpl_CreateEffect(IDirectInputDevice8W *iface, - const GUID *type, const DIEFFECT *params, IDirectInputEffect **out, - IUnknown *outer) -{ - JoystickImpl *This = impl_from_IDirectInputDevice8W(iface); - EffectImpl *effect; - HRESULT hr; - - TRACE("%p %s %p %p %p\n", iface, debugstr_guid(type), params, out, outer); - dump_DIEFFECT(params, type, 0); - - if(!This->ff){ - TRACE("No force feedback support\n"); - *out = NULL; - return S_OK; - } - - if(outer) - WARN("aggregation not implemented\n"); - - effect = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); - effect->IDirectInputEffect_iface.lpVtbl = &EffectVtbl; - effect->ref = 1; - effect->guid = *type; - effect->device = This; - - /* Mac's FFEFFECT and Win's DIEFFECT are binary identical. */ - hr = osx_to_win32_hresult(FFDeviceCreateEffect(This->ff, - effect_win_to_mac(type), (FFEFFECT*)params, &effect->effect)); - if(FAILED(hr)){ - WARN("FFDeviceCreateEffect failed: %08x\n", hr); - HeapFree(GetProcessHeap(), 0, effect); - return hr; - } - - list_add_tail(&This->effects, &effect->entry); - *out = &effect->IDirectInputEffect_iface; - - TRACE("allocated effect: %p\n", effect); - - return S_OK; -} - -static HRESULT WINAPI JoystickAImpl_CreateEffect(IDirectInputDevice8A *iface, - const GUID *type, const DIEFFECT *params, IDirectInputEffect **out, - IUnknown *outer) -{ - JoystickImpl *This = impl_from_IDirectInputDevice8A(iface); - - TRACE("%p %s %p %p %p\n", iface, debugstr_guid(type), params, out, outer); - - return JoystickWImpl_CreateEffect(&This->generic.base.IDirectInputDevice8W_iface, - type, params, out, outer); -} - -static HRESULT WINAPI JoystickWImpl_SendForceFeedbackCommand(IDirectInputDevice8W *iface, - DWORD flags) -{ - JoystickImpl *This = impl_from_IDirectInputDevice8W(iface); - HRESULT hr; - - TRACE("%p 0x%x\n", This, flags); - - if(!This->ff) - return DI_NOEFFECT; - - hr = osx_to_win32_hresult(FFDeviceSendForceFeedbackCommand(This->ff, flags)); - if(FAILED(hr)){ - WARN("FFDeviceSendForceFeedbackCommand failed: %08x\n", hr); - return hr; - } - - return S_OK; -} - -static HRESULT WINAPI JoystickAImpl_SendForceFeedbackCommand(IDirectInputDevice8A *iface, - DWORD flags) -{ - JoystickImpl *This = impl_from_IDirectInputDevice8A(iface); - - TRACE("%p 0x%x\n", This, flags); - - return JoystickWImpl_SendForceFeedbackCommand(&This->generic.base.IDirectInputDevice8W_iface, flags); -} - -const struct dinput_device joystick_osx_device = { - "Wine OS X joystick driver", - joydev_enum_deviceA, - joydev_enum_deviceW, - joydev_create_device -}; - -static const IDirectInputDevice8AVtbl JoystickAvt = -{ - IDirectInputDevice2AImpl_QueryInterface, - IDirectInputDevice2AImpl_AddRef, - IDirectInputDevice2AImpl_Release, - JoystickAGenericImpl_GetCapabilities, - IDirectInputDevice2AImpl_EnumObjects, - JoystickAGenericImpl_GetProperty, - JoystickAImpl_SetProperty, - IDirectInputDevice2AImpl_Acquire, - IDirectInputDevice2AImpl_Unacquire, - JoystickAGenericImpl_GetDeviceState, - IDirectInputDevice2AImpl_GetDeviceData, - IDirectInputDevice2AImpl_SetDataFormat, - IDirectInputDevice2AImpl_SetEventNotification, - IDirectInputDevice2AImpl_SetCooperativeLevel, - JoystickAGenericImpl_GetObjectInfo, - JoystickAGenericImpl_GetDeviceInfo, - IDirectInputDevice2AImpl_RunControlPanel, - IDirectInputDevice2AImpl_Initialize, - JoystickAImpl_CreateEffect, - IDirectInputDevice2AImpl_EnumEffects, - IDirectInputDevice2AImpl_GetEffectInfo, - IDirectInputDevice2AImpl_GetForceFeedbackState, - JoystickAImpl_SendForceFeedbackCommand, - IDirectInputDevice2AImpl_EnumCreatedEffectObjects, - IDirectInputDevice2AImpl_Escape, - JoystickAGenericImpl_Poll, - IDirectInputDevice2AImpl_SendDeviceData, - IDirectInputDevice7AImpl_EnumEffectsInFile, - IDirectInputDevice7AImpl_WriteEffectToFile, - JoystickAGenericImpl_BuildActionMap, - JoystickAGenericImpl_SetActionMap, - IDirectInputDevice8AImpl_GetImageInfo -}; - -static const IDirectInputDevice8WVtbl JoystickWvt = -{ - IDirectInputDevice2WImpl_QueryInterface, - IDirectInputDevice2WImpl_AddRef, - IDirectInputDevice2WImpl_Release, - JoystickWGenericImpl_GetCapabilities, - IDirectInputDevice2WImpl_EnumObjects, - JoystickWGenericImpl_GetProperty, - JoystickWImpl_SetProperty, - IDirectInputDevice2WImpl_Acquire, - IDirectInputDevice2WImpl_Unacquire, - JoystickWGenericImpl_GetDeviceState, - IDirectInputDevice2WImpl_GetDeviceData, - IDirectInputDevice2WImpl_SetDataFormat, - IDirectInputDevice2WImpl_SetEventNotification, - IDirectInputDevice2WImpl_SetCooperativeLevel, - JoystickWGenericImpl_GetObjectInfo, - JoystickWGenericImpl_GetDeviceInfo, - IDirectInputDevice2WImpl_RunControlPanel, - IDirectInputDevice2WImpl_Initialize, - JoystickWImpl_CreateEffect, - IDirectInputDevice2WImpl_EnumEffects, - IDirectInputDevice2WImpl_GetEffectInfo, - IDirectInputDevice2WImpl_GetForceFeedbackState, - JoystickWImpl_SendForceFeedbackCommand, - IDirectInputDevice2WImpl_EnumCreatedEffectObjects, - IDirectInputDevice2WImpl_Escape, - JoystickWGenericImpl_Poll, - IDirectInputDevice2WImpl_SendDeviceData, - IDirectInputDevice7WImpl_EnumEffectsInFile, - IDirectInputDevice7WImpl_WriteEffectToFile, - JoystickWGenericImpl_BuildActionMap, - JoystickWGenericImpl_SetActionMap, - IDirectInputDevice8WImpl_GetImageInfo -}; - -static HRESULT WINAPI effect_QueryInterface(IDirectInputEffect *iface, - const GUID *guid, void **out) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - - TRACE("%p %s %p\n", This, debugstr_guid(guid), out); - - if(IsEqualIID(guid, &IID_IDirectInputEffect)){ - *out = iface; - IDirectInputEffect_AddRef(iface); - return S_OK; - } - - return E_NOINTERFACE; -} - -static ULONG WINAPI effect_AddRef(IDirectInputEffect *iface) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - ULONG ref = InterlockedIncrement(&This->ref); - TRACE("%p, ref is now: %u\n", This, ref); - return ref; -} - -static ULONG WINAPI effect_Release(IDirectInputEffect *iface) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - ULONG ref = InterlockedDecrement(&This->ref); - TRACE("%p, ref is now: %u\n", This, ref); - - if(!ref){ - list_remove(&This->entry); - FFDeviceReleaseEffect(This->device->ff, This->effect); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI effect_Initialize(IDirectInputEffect *iface, HINSTANCE hinst, - DWORD version, const GUID *guid) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p %p 0x%x, %s\n", This, hinst, version, debugstr_guid(guid)); - return S_OK; -} - -static HRESULT WINAPI effect_GetEffectGuid(IDirectInputEffect *iface, GUID *out) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p %p\n", This, out); - *out = This->guid; - return S_OK; -} - -static HRESULT WINAPI effect_GetParameters(IDirectInputEffect *iface, - DIEFFECT *effect, DWORD flags) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p %p 0x%x\n", This, effect, flags); - return osx_to_win32_hresult(FFEffectGetParameters(This->effect, (FFEFFECT*)effect, flags)); -} - -static HRESULT WINAPI effect_SetParameters(IDirectInputEffect *iface, - const DIEFFECT *effect, DWORD flags) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p %p 0x%x\n", This, effect, flags); - dump_DIEFFECT(effect, &This->guid, flags); - return osx_to_win32_hresult(FFEffectSetParameters(This->effect, (FFEFFECT*)effect, flags)); -} - -static HRESULT WINAPI effect_Start(IDirectInputEffect *iface, DWORD iterations, - DWORD flags) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p 0x%x 0x%x\n", This, iterations, flags); - return osx_to_win32_hresult(FFEffectStart(This->effect, iterations, flags)); -} - -static HRESULT WINAPI effect_Stop(IDirectInputEffect *iface) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p\n", This); - return osx_to_win32_hresult(FFEffectStop(This->effect)); -} - -static HRESULT WINAPI effect_GetEffectStatus(IDirectInputEffect *iface, DWORD *flags) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p %p\n", This, flags); - return osx_to_win32_hresult(FFEffectGetEffectStatus(This->effect, (UInt32*)flags)); -} - -static HRESULT WINAPI effect_Download(IDirectInputEffect *iface) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p\n", This); - return osx_to_win32_hresult(FFEffectDownload(This->effect)); -} - -static HRESULT WINAPI effect_Unload(IDirectInputEffect *iface) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p\n", This); - return osx_to_win32_hresult(FFEffectUnload(This->effect)); -} - -static HRESULT WINAPI effect_Escape(IDirectInputEffect *iface, DIEFFESCAPE *escape) -{ - EffectImpl *This = impl_from_IDirectInputEffect(iface); - TRACE("%p %p\n", This, escape); - return osx_to_win32_hresult(FFEffectEscape(This->effect, (FFEFFESCAPE*)escape)); -} - -static const IDirectInputEffectVtbl EffectVtbl = { - effect_QueryInterface, - effect_AddRef, - effect_Release, - effect_Initialize, - effect_GetEffectGuid, - effect_GetParameters, - effect_SetParameters, - effect_Start, - effect_Stop, - effect_GetEffectStatus, - effect_Download, - effect_Unload, - effect_Escape -}; - -#else /* HAVE_IOHIDMANAGERCREATE */ - -const struct dinput_device joystick_osx_device = { - "Wine OS X joystick driver", - NULL, - NULL, - NULL -}; - -#endif /* HAVE_IOHIDMANAGERCREATE */ diff --git a/dlls/winejoystick.drv/Makefile.in b/dlls/winejoystick.drv/Makefile.in index 117c7f1..d827581 100644 --- a/dlls/winejoystick.drv/Makefile.in +++ b/dlls/winejoystick.drv/Makefile.in @@ -1,9 +1,7 @@ MODULE = winejoystick.drv IMPORTS = winmm user32 advapi32 -EXTRALIBS = $(IOKIT_LIBS) C_SRCS = \ joystick.c \ joystick_driver.c \ - joystick_linux.c \ - joystick_osx.c + joystick_linux.c diff --git a/dlls/winejoystick.drv/joystick_driver.c b/dlls/winejoystick.drv/joystick_driver.c index 785f8b5..d86e947 100644 --- a/dlls/winejoystick.drv/joystick_driver.c +++ b/dlls/winejoystick.drv/joystick_driver.c @@ -23,7 +23,6 @@ #include "wine/port.h" #ifndef HAVE_LINUX_JOYSTICK_H -#if !defined(HAVE_IOKIT_HID_IOHIDLIB_H) #include #include @@ -501,4 +500,3 @@ static GAMEPAD_DRIVER null_driver = }; #endif /* HAVE_LINUX_JOYSTICK_H */ -#endif /* HAVE_IOKIT_HID_IOHIDLIB_H */ diff --git a/dlls/winejoystick.drv/joystick_osx.c b/dlls/winejoystick.drv/joystick_osx.c deleted file mode 100644 index da45450..0000000 --- a/dlls/winejoystick.drv/joystick_osx.c +++ /dev/null @@ -1,753 +0,0 @@ -/* - * WinMM joystick driver OS X implementation - * - * Copyright 1997 Andreas Mohr - * Copyright 1998 Marcus Meissner - * Copyright 1998,1999 Lionel Ulmer - * Copyright 2000 Wolfgang Schwotzer - * Copyright 2000-2001 TransGaming Technologies Inc. - * Copyright 2002 David Hagood - * Copyright 2009 CodeWeavers, Aric Stewart - * Copyright 2015 Ken Thomases for CodeWeavers Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#if defined(HAVE_IOKIT_HID_IOHIDLIB_H) - -#define DWORD UInt32 -#define LPDWORD UInt32* -#define LONG SInt32 -#define LPLONG SInt32* -#define E_PENDING __carbon_E_PENDING -#define ULONG __carbon_ULONG -#define E_INVALIDARG __carbon_E_INVALIDARG -#define E_OUTOFMEMORY __carbon_E_OUTOFMEMORY -#define E_HANDLE __carbon_E_HANDLE -#define E_ACCESSDENIED __carbon_E_ACCESSDENIED -#define E_UNEXPECTED __carbon_E_UNEXPECTED -#define E_FAIL __carbon_E_FAIL -#define E_ABORT __carbon_E_ABORT -#define E_POINTER __carbon_E_POINTER -#define E_NOINTERFACE __carbon_E_NOINTERFACE -#define E_NOTIMPL __carbon_E_NOTIMPL -#define S_FALSE __carbon_S_FALSE -#define S_OK __carbon_S_OK -#define HRESULT_FACILITY __carbon_HRESULT_FACILITY -#define IS_ERROR __carbon_IS_ERROR -#define FAILED __carbon_FAILED -#define SUCCEEDED __carbon_SUCCEEDED -#define MAKE_HRESULT __carbon_MAKE_HRESULT -#define HRESULT __carbon_HRESULT -#define STDMETHODCALLTYPE __carbon_STDMETHODCALLTYPE -#include -#include -#undef ULONG -#undef E_INVALIDARG -#undef E_OUTOFMEMORY -#undef E_HANDLE -#undef E_ACCESSDENIED -#undef E_UNEXPECTED -#undef E_FAIL -#undef E_ABORT -#undef E_POINTER -#undef E_NOINTERFACE -#undef E_NOTIMPL -#undef S_FALSE -#undef S_OK -#undef HRESULT_FACILITY -#undef IS_ERROR -#undef FAILED -#undef SUCCEEDED -#undef MAKE_HRESULT -#undef HRESULT -#undef STDMETHODCALLTYPE -#undef DWORD -#undef LPDWORD -#undef LONG -#undef LPLONG -#undef E_PENDING - -#include "joystick.h" - -#include "wine/debug.h" - - -WINE_DEFAULT_DEBUG_CHANNEL(joystick); - - -#define MAXJOYSTICK (JOYSTICKID2 + 30) - - -enum { - AXIS_X, - AXIS_Y, - AXIS_Z, - AXIS_RX, - AXIS_RY, - AXIS_RZ, - NUM_AXES -}; - -struct axis { - IOHIDElementRef element; - CFIndex min_value, max_value; -}; - -typedef struct { - BOOL in_use; - IOHIDElementRef element; - struct axis axes[NUM_AXES]; - CFMutableArrayRef buttons; - IOHIDElementRef hatswitch; -} joystick_t; - - -static joystick_t joysticks[MAXJOYSTICK]; -static CFMutableArrayRef device_main_elements = NULL; - - -static const char* debugstr_cf(CFTypeRef t) -{ - CFStringRef s; - const char* ret; - - if (!t) return "(null)"; - - if (CFGetTypeID(t) == CFStringGetTypeID()) - s = t; - else - s = CFCopyDescription(t); - ret = CFStringGetCStringPtr(s, kCFStringEncodingUTF8); - if (ret) ret = debugstr_a(ret); - if (!ret) - { - const UniChar* u = CFStringGetCharactersPtr(s); - if (u) - ret = debugstr_wn((const WCHAR*)u, CFStringGetLength(s)); - } - if (!ret) - { - UniChar buf[200]; - int len = min(CFStringGetLength(s), sizeof(buf)/sizeof(buf[0])); - CFStringGetCharacters(s, CFRangeMake(0, len), buf); - ret = debugstr_wn(buf, len); - } - if (s != t) CFRelease(s); - return ret; -} - -static const char* debugstr_device(IOHIDDeviceRef device) -{ - return wine_dbg_sprintf("", device, - debugstr_cf(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)))); -} - -static const char* debugstr_element(IOHIDElementRef element) -{ - return wine_dbg_sprintf("", element, - IOHIDElementGetType(element), IOHIDElementGetUsagePage(element), - IOHIDElementGetUsage(element), IOHIDElementGetDevice(element)); -} - - -static int axis_for_usage(int usage) -{ - switch (usage) - { - case kHIDUsage_GD_X: return AXIS_X; - case kHIDUsage_GD_Y: return AXIS_Y; - case kHIDUsage_GD_Z: return AXIS_Z; - case kHIDUsage_GD_Rx: return AXIS_RX; - case kHIDUsage_GD_Ry: return AXIS_RY; - case kHIDUsage_GD_Rz: return AXIS_RZ; - } - - return -1; -} - - -/************************************************************************** - * joystick_from_id - */ -static joystick_t* joystick_from_id(DWORD_PTR device_id) -{ - int index; - - if ((device_id - (DWORD_PTR)joysticks) % sizeof(joysticks[0]) != 0) - return NULL; - index = (device_id - (DWORD_PTR)joysticks) / sizeof(joysticks[0]); - if (index < 0 || index >= MAXJOYSTICK || !((joystick_t*)device_id)->in_use) - return NULL; - - return (joystick_t*)device_id; -} - -/************************************************************************** - * create_osx_device_match - */ -static CFDictionaryRef create_osx_device_match(int usage) -{ - CFDictionaryRef result = NULL; - int number; - CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) }; - CFNumberRef values[2]; - int i; - - TRACE("usage %d\n", usage); - - number = kHIDPage_GenericDesktop; - values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &number); - values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); - - if (values[0] && values[1]) - { - result = CFDictionaryCreate(NULL, (const void**)keys, (const void**)values, sizeof(values) / sizeof(values[0]), - &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - if (!result) - ERR("CFDictionaryCreate failed.\n"); - } - else - ERR("CFNumberCreate failed.\n"); - - for (i = 0; i < sizeof(values) / sizeof(values[0]); i++) - if (values[i]) CFRelease(values[i]); - - return result; -} - -/************************************************************************** - * find_top_level - */ -static CFIndex find_top_level(IOHIDDeviceRef hid_device, CFMutableArrayRef main_elements) -{ - CFArrayRef elements; - CFIndex total = 0; - - TRACE("hid_device %s\n", debugstr_device(hid_device)); - - if (!hid_device) - return 0; - - elements = IOHIDDeviceCopyMatchingElements(hid_device, NULL, 0); - - if (elements) - { - CFIndex i, count = CFArrayGetCount(elements); - for (i = 0; i < count; i++) - { - IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i); - int type = IOHIDElementGetType(element); - - TRACE("element %s\n", debugstr_element(element)); - - /* Check for top-level gaming device collections */ - if (type == kIOHIDElementTypeCollection && IOHIDElementGetParent(element) == 0) - { - int usage_page = IOHIDElementGetUsagePage(element); - int usage = IOHIDElementGetUsage(element); - - if (usage_page == kHIDPage_GenericDesktop && - (usage == kHIDUsage_GD_Joystick || usage == kHIDUsage_GD_GamePad)) - { - CFArrayAppendValue(main_elements, element); - total++; - } - } - } - CFRelease(elements); - } - - TRACE("-> total %d\n", (int)total); - return total; -} - -/************************************************************************** - * find_osx_devices - */ -static int find_osx_devices(void) -{ - IOHIDManagerRef hid_manager; - int usages[] = { kHIDUsage_GD_Joystick, kHIDUsage_GD_GamePad }; - int i; - CFDictionaryRef matching_dicts[sizeof(usages) / sizeof(usages[0])]; - CFArrayRef matching; - CFSetRef devset; - - TRACE("()\n"); - - hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, 0L); - if (IOHIDManagerOpen(hid_manager, 0) != kIOReturnSuccess) - { - ERR("Couldn't open IOHIDManager.\n"); - CFRelease(hid_manager); - return 0; - } - - for (i = 0; i < sizeof(matching_dicts) / sizeof(matching_dicts[0]); i++) - { - matching_dicts[i] = create_osx_device_match(usages[i]); - if (!matching_dicts[i]) - { - while (i > 0) - CFRelease(matching_dicts[--i]); - goto fail; - } - } - - matching = CFArrayCreate(NULL, (const void**)matching_dicts, sizeof(matching_dicts) / sizeof(matching_dicts[0]), - &kCFTypeArrayCallBacks); - - for (i = 0; i < sizeof(matching_dicts) / sizeof(matching_dicts[0]); i++) - CFRelease(matching_dicts[i]); - - IOHIDManagerSetDeviceMatchingMultiple(hid_manager, matching); - CFRelease(matching); - devset = IOHIDManagerCopyDevices(hid_manager); - if (devset) - { - CFIndex num_devices, num_main_elements; - const void** refs; - CFArrayRef devices; - - num_devices = CFSetGetCount(devset); - refs = HeapAlloc(GetProcessHeap(), 0, num_devices * sizeof(*refs)); - if (!refs) - { - CFRelease(devset); - goto fail; - } - - CFSetGetValues(devset, refs); - devices = CFArrayCreate(NULL, refs, num_devices, &kCFTypeArrayCallBacks); - HeapFree(GetProcessHeap(), 0, refs); - CFRelease(devset); - if (!devices) - goto fail; - - device_main_elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - if (!device_main_elements) - { - CFRelease(devices); - goto fail; - } - - num_main_elements = 0; - for (i = 0; i < num_devices; i++) - { - IOHIDDeviceRef hid_device = (IOHIDDeviceRef)CFArrayGetValueAtIndex(devices, i); - TRACE("hid_device %s\n", debugstr_device(hid_device)); - num_main_elements += find_top_level(hid_device, device_main_elements); - } - - CFRelease(devices); - - TRACE("found %i device(s), %i collection(s)\n",(int)num_devices,(int)num_main_elements); - return (int)num_main_elements; - } - -fail: - IOHIDManagerClose(hid_manager, 0); - CFRelease(hid_manager); - return 0; -} - -/************************************************************************** - * collect_joystick_elements - */ -static void collect_joystick_elements(joystick_t* joystick, IOHIDElementRef collection) -{ - CFIndex i, count; - CFArrayRef children = IOHIDElementGetChildren(collection); - - TRACE("collection %s\n", debugstr_element(collection)); - - count = CFArrayGetCount(children); - for (i = 0; i < count; i++) - { - IOHIDElementRef child; - int type; - - child = (IOHIDElementRef)CFArrayGetValueAtIndex(children, i); - TRACE("child %s\n", debugstr_element(child)); - type = IOHIDElementGetType(child); - switch (type) - { - case kIOHIDElementTypeCollection: - collect_joystick_elements(joystick, child); - break; - case kIOHIDElementTypeInput_Button: - { - int usage_page = IOHIDElementGetUsagePage(child); - - TRACE("kIOHIDElementTypeInput_Button usage_page %d\n", usage_page); - - /* avoid strange elements found on the 360 controller */ - if (usage_page == kHIDPage_Button) - CFArrayAppendValue(joystick->buttons, child); - break; - } - case kIOHIDElementTypeInput_Axis: - { - TRACE("kIOHIDElementTypeInput_Axis; ignoring\n"); - break; - } - case kIOHIDElementTypeInput_Misc: - { - uint32_t usage = IOHIDElementGetUsage( child ); - switch(usage) - { - case kHIDUsage_GD_Hatswitch: - { - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Hatswitch\n"); - if (joystick->hatswitch) - TRACE(" ignoring additional hatswitch\n"); - else - joystick->hatswitch = (IOHIDElementRef)CFRetain(child); - break; - } - case kHIDUsage_GD_X: - case kHIDUsage_GD_Y: - case kHIDUsage_GD_Z: - case kHIDUsage_GD_Rx: - case kHIDUsage_GD_Ry: - case kHIDUsage_GD_Rz: - { - int axis = axis_for_usage(usage); - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_ (%d) axis %d\n", usage, axis); - if (axis < 0 || joystick->axes[axis].element) - TRACE(" ignoring\n"); - else - { - joystick->axes[axis].element = (IOHIDElementRef)CFRetain(child); - joystick->axes[axis].min_value = IOHIDElementGetLogicalMin(child); - joystick->axes[axis].max_value = IOHIDElementGetLogicalMax(child); - } - break; - } - case kHIDUsage_GD_Slider: - TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Slider; ignoring\n"); - break; - default: - FIXME("kIOHIDElementTypeInput_Misc / Unhandled usage %d\n", usage); - break; - } - break; - } - default: - FIXME("Unhandled type %i\n",type); - break; - } - } -} - -/************************************************************************** - * button_usage_comparator - */ -static CFComparisonResult button_usage_comparator(const void *val1, const void *val2, void *context) -{ - IOHIDElementRef element1 = (IOHIDElementRef)val1, element2 = (IOHIDElementRef)val2; - int usage1 = IOHIDElementGetUsage(element1), usage2 = IOHIDElementGetUsage(element2); - - if (usage1 < usage2) - return kCFCompareLessThan; - if (usage1 > usage2) - return kCFCompareGreaterThan; - return kCFCompareEqualTo; -} - -/************************************************************************** - * driver_open - */ -LRESULT driver_open(LPSTR str, DWORD index) -{ - if (index >= MAXJOYSTICK || joysticks[index].in_use) - return 0; - - joysticks[index].in_use = TRUE; - return (LRESULT)&joysticks[index]; -} - -/************************************************************************** - * driver_close - */ -LRESULT driver_close(DWORD_PTR device_id) -{ - joystick_t* joystick = joystick_from_id(device_id); - int i; - - if (joystick == NULL) - return 0; - - CFRelease(joystick->element); - for (i = 0; i < NUM_AXES; i++) - { - if (joystick->axes[i].element) - CFRelease(joystick->axes[i].element); - } - if (joystick->buttons) - CFRelease(joystick->buttons); - if (joystick->hatswitch) - CFRelease(joystick->hatswitch); - - memset(joystick, 0, sizeof(*joystick)); - return 1; -} - -/************************************************************************** - * open_joystick - */ -static BOOL open_joystick(joystick_t* joystick) -{ - CFIndex index; - CFRange range; - - if (joystick->element) - return TRUE; - - if (!device_main_elements) - { - find_osx_devices(); - if (!device_main_elements) - return FALSE; - } - - index = joystick - joysticks; - if (index >= CFArrayGetCount(device_main_elements)) - return FALSE; - - joystick->element = (IOHIDElementRef)CFArrayGetValueAtIndex(device_main_elements, index); - joystick->buttons = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - collect_joystick_elements(joystick, joystick->element); - - /* Sort buttons into correct order */ - range.location = 0; - range.length = CFArrayGetCount(joystick->buttons); - CFArraySortValues(joystick->buttons, range, button_usage_comparator, NULL); - if (range.length > 32) - { - /* Delete any buttons beyond the first 32 */ - range.location = 32; - range.length -= 32; - CFArrayReplaceValues(joystick->buttons, range, NULL, 0); - } - - return TRUE; -} - - -/************************************************************************** - * driver_joyGetDevCaps - */ -LRESULT driver_joyGetDevCaps(DWORD_PTR device_id, JOYCAPSW* caps, DWORD size) -{ - joystick_t* joystick; - IOHIDDeviceRef device; - - if ((joystick = joystick_from_id(device_id)) == NULL) - return MMSYSERR_NODRIVER; - - if (!open_joystick(joystick)) - return JOYERR_PARMS; - - caps->szPname[0] = 0; - - device = IOHIDElementGetDevice(joystick->element); - if (device) - { - CFStringRef product_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); - if (product_name) - { - CFRange range; - - range.location = 0; - range.length = min(MAXPNAMELEN - 1, CFStringGetLength(product_name)); - CFStringGetCharacters(product_name, range, (UniChar*)caps->szPname); - caps->szPname[range.length] = 0; - } - } - - caps->wMid = MM_MICROSOFT; - caps->wPid = MM_PC_JOYSTICK; - caps->wXmin = 0; - caps->wXmax = 0xFFFF; - caps->wYmin = 0; - caps->wYmax = 0xFFFF; - caps->wZmin = 0; - caps->wZmax = joystick->axes[AXIS_Z].element ? 0xFFFF : 0; - caps->wNumButtons = CFArrayGetCount(joystick->buttons); - if (size == sizeof(JOYCAPSW)) - { - int i; - - /* complete 95 structure */ - caps->wRmin = 0; - caps->wRmax = 0xFFFF; - caps->wUmin = 0; - caps->wUmax = 0xFFFF; - caps->wVmin = 0; - caps->wVmax = 0xFFFF; - caps->wMaxAxes = 6; /* same as MS Joystick Driver */ - caps->wNumAxes = 0; - caps->wMaxButtons = 32; /* same as MS Joystick Driver */ - caps->szRegKey[0] = 0; - caps->szOEMVxD[0] = 0; - caps->wCaps = 0; - - for (i = 0; i < NUM_AXES; i++) - { - if (joystick->axes[i].element) - { - caps->wNumAxes++; - switch (i) - { - case AXIS_Z: caps->wCaps |= JOYCAPS_HASZ; break; - case AXIS_RX: caps->wCaps |= JOYCAPS_HASU; break; - case AXIS_RY: caps->wCaps |= JOYCAPS_HASV; break; - case AXIS_RZ: caps->wCaps |= JOYCAPS_HASR; break; - } - } - } - - if (joystick->hatswitch) - caps->wCaps |= JOYCAPS_HASPOV | JOYCAPS_POV4DIR; - } - - TRACE("name %s buttons %u axes %d caps 0x%08x\n", debugstr_w(caps->szPname), caps->wNumButtons, caps->wNumAxes, caps->wCaps); - - return JOYERR_NOERROR; -} - -/************************************************************************** - * driver_joyGetPosEx - */ -LRESULT driver_joyGetPosEx(DWORD_PTR device_id, JOYINFOEX* info) -{ - static const struct { - DWORD flag; - off_t offset; - } axis_map[NUM_AXES] = { - { JOY_RETURNX, FIELD_OFFSET(JOYINFOEX, dwXpos) }, - { JOY_RETURNY, FIELD_OFFSET(JOYINFOEX, dwYpos) }, - { JOY_RETURNZ, FIELD_OFFSET(JOYINFOEX, dwZpos) }, - { JOY_RETURNU, FIELD_OFFSET(JOYINFOEX, dwUpos) }, - { JOY_RETURNV, FIELD_OFFSET(JOYINFOEX, dwVpos) }, - { JOY_RETURNR, FIELD_OFFSET(JOYINFOEX, dwRpos) }, - }; - - joystick_t* joystick; - IOHIDDeviceRef device; - CFIndex i, count; - IOHIDValueRef valueRef; - long value; - - if ((joystick = joystick_from_id(device_id)) == NULL) - return MMSYSERR_NODRIVER; - - if (!open_joystick(joystick)) - return JOYERR_PARMS; - - device = IOHIDElementGetDevice(joystick->element); - - if (info->dwFlags & JOY_RETURNBUTTONS) - { - info->dwButtons = 0; - info->dwButtonNumber = 0; - - count = CFArrayGetCount(joystick->buttons); - for (i = 0; i < count; i++) - { - IOHIDElementRef button = (IOHIDElementRef)CFArrayGetValueAtIndex(joystick->buttons, i); - IOHIDDeviceGetValue(device, button, &valueRef); - value = IOHIDValueGetIntegerValue(valueRef); - if (value) - { - info->dwButtons |= 1 << i; - info->dwButtonNumber++; - } - } - } - - for (i = 0; i < NUM_AXES; i++) - { - if (info->dwFlags & axis_map[i].flag) - { - DWORD* field = (DWORD*)((char*)info + axis_map[i].offset); - if (joystick->axes[i].element) - { - IOHIDDeviceGetValue(device, joystick->axes[i].element, &valueRef); - value = IOHIDValueGetIntegerValue(valueRef) - joystick->axes[i].min_value; - *field = MulDiv(value, 0xFFFF, joystick->axes[i].max_value - joystick->axes[i].min_value); - } - else - { - *field = 0; - info->dwFlags &= ~axis_map[i].flag; - } - } - } - - if (info->dwFlags & JOY_RETURNPOV) - { - if (joystick->hatswitch) - { - IOHIDDeviceGetValue(device, joystick->hatswitch, &valueRef); - value = IOHIDValueGetIntegerValue(valueRef); - if (value >= 8) - info->dwPOV = JOY_POVCENTERED; - else - info->dwPOV = value * 4500; - } - else - { - info->dwPOV = 0; - info->dwFlags &= ~JOY_RETURNPOV; - } - } - - TRACE("x: %d, y: %d, z: %d, r: %d, u: %d, v: %d, buttons: 0x%04x, pov %d, flags: 0x%04x\n", - info->dwXpos, info->dwYpos, info->dwZpos, info->dwRpos, info->dwUpos, info->dwVpos, info->dwButtons, info->dwPOV, info->dwFlags); - - return JOYERR_NOERROR; -} - -/************************************************************************** - * driver_joyGetPos - */ -LRESULT driver_joyGetPos(DWORD_PTR device_id, JOYINFO* info) -{ - JOYINFOEX ji; - LONG ret; - - memset(&ji, 0, sizeof(ji)); - - ji.dwSize = sizeof(ji); - ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNBUTTONS; - ret = driver_joyGetPosEx(device_id, &ji); - if (ret == JOYERR_NOERROR) - { - info->wXpos = ji.dwXpos; - info->wYpos = ji.dwYpos; - info->wZpos = ji.dwZpos; - info->wButtons = ji.dwButtons; - } - - return ret; -} - -#endif /* HAVE_IOKIT_HID_IOHIDLIB_H */