/*  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 <IOKit/IOKitLib.h>
#include <IOKit/hid/IOHIDLib.h>
#include <ForceFeedback/ForceFeedback.h>
#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("<IOHIDDevice %p product %s>", device,
                            debugstr_cf(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey))));
}

static const char* debugstr_element(IOHIDElementRef element)
{
    return wine_dbg_sprintf("<IOHIDElement %p type %d usage %u/%u device %p>", 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<cnt; idx++)
        {
            IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, idx);
            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;
}

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<cnt; idx++)
    {
        IOHIDElementRef child;

        child = (IOHIDElementRef)CFArrayGetValueAtIndex(element_children, idx);
        TRACE("child %s\n", debugstr_element(child));
        if (IOHIDElementGetType(child) == kIOHIDElementTypeCollection)
            get_element_children(child, all_children);
        else
            CFArrayAppendValue(all_children, child);
    }
}

static int find_osx_devices(void)
{
    IOHIDManagerRef hid_manager;
    CFMutableDictionaryRef result;
    CFSetRef devset;
    CFMutableArrayRef matching;

    TRACE("()\n");

    hid_manager = IOHIDManagerCreate( kCFAllocatorDefault, 0L );
    if (IOHIDManagerOpen( hid_manager, 0 ) != kIOReturnSuccess)
    {
        ERR("Couldn't open IOHIDManager.\n");
        CFRelease( hid_manager );
        return 0;
    }

     matching = CFArrayCreateMutable( kCFAllocatorDefault, 0,
                        &kCFTypeArrayCallBacks );

    /* build matching dictionary */
    result = create_osx_device_match(kHIDUsage_GD_Joystick);
    if (!result)
    {
        CFRelease(matching);
        goto fail;
    }
    CFArrayAppendValue( matching, result );
    CFRelease( result );
    result = create_osx_device_match(kHIDUsage_GD_GamePad);
    if (!result)
    {
        CFRelease(matching);
        goto fail;
    }
    CFArrayAppendValue( matching, result );
    CFRelease( result );

    IOHIDManagerSetDeviceMatchingMultiple( hid_manager, matching);
    CFRelease( matching );
    devset = IOHIDManagerCopyDevices( hid_manager );
    if (devset)
    {
        CFIndex num_devices, num_main_elements, idx;
        CFMutableArrayRef devices = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
        CFSetApplyFunction(devset, CFSetApplierFunctionCopyToCFArray, devices);
        CFRelease( devset);
        num_devices = CFArrayGetCount(devices);

        device_main_elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
        if (!device_main_elements)
        {
            CFRelease( devices );
            goto fail;
        }

        num_main_elements = 0;
        for (idx = 0; idx < num_devices; idx++)
        {
            CFIndex top;
            IOHIDDeviceRef hid_device;

            hid_device = (IOHIDDeviceRef) CFArrayGetValueAtIndex(devices, idx);
            TRACE("hid_device %s\n", debugstr_device(hid_device));
            top = find_top_level(hid_device, device_main_elements);
            num_main_elements += top;
        }

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

static int get_osx_device_name(int id, char *name, int length)
{
    CFStringRef str;
    IOHIDDeviceRef hid_device;

    hid_device = get_device_ref(id);

    TRACE("id %d hid_device %s\n", id, debugstr_device(hid_device));

    if (name)
        name[0] = 0;

    if (!hid_device)
        return 0;

    str = IOHIDDeviceGetProperty(hid_device, CFSTR( kIOHIDProductKey ));
    if (str)
    {
        CFIndex len = CFStringGetLength(str);
        if (length >= 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_IUnknown) || 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 */
