/*
 * 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.
 * Copyright 2016 David Lawrie
 *
 * 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 <IOKit/IOKitLib.h>
#include <IOKit/hid/IOHIDLib.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

#include "joystick.h"

#include "wine/debug.h"


WINE_DEFAULT_DEBUG_CHANNEL(joystick);


#define MAXJOYSTICK (JOYSTICKID2 + 30)


enum {
    AXIS_X,  /* Winmm X */
    AXIS_Y,  /* Winmm Y */
    AXIS_Z,  /* Winmm Z */
    AXIS_RX, /* Winmm V */
    AXIS_RY, /* Winmm U */
    AXIS_RZ, /* Winmm R */
    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 long get_device_property_long(IOHIDDeviceRef device, CFStringRef key)
{
    CFTypeRef ref;
    long result = 0;

    if (device)
    {
        assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device));

        ref = IOHIDDeviceGetProperty(device, key);

        if (ref && CFNumberGetTypeID() == CFGetTypeID(ref))
            CFNumberGetValue((CFNumberRef)ref, kCFNumberLongType, &result);
    }

    return result;
}

static CFStringRef copy_device_name(IOHIDDeviceRef device)
{
    CFStringRef name;

    if (device)
    {
        CFTypeRef ref_name;

        assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device));

        ref_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));

        if (ref_name && CFStringGetTypeID() == CFGetTypeID(ref_name))
            name = CFStringCreateCopy(kCFAllocatorDefault, ref_name);
        else
        {
            long vendID, prodID;

            vendID = get_device_property_long(device, CFSTR(kIOHIDVendorIDKey));
            prodID = get_device_property_long(device, CFSTR(kIOHIDProductIDKey));
            name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("0x%04lx 0x%04lx"), vendID, prodID);
        }
    }
    else
    {
        ERR("NULL device\n");
        name = CFStringCreateCopy(kCFAllocatorDefault, CFSTR(""));
    }

    return name;
}

static long get_device_location_ID(IOHIDDeviceRef device)
{
    return get_device_property_long(device, CFSTR(kIOHIDLocationIDKey));
}

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 IOHIDLocationID %lu>", device,
                            debugstr_cf(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey))),
                            get_device_location_ID(device));
}

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 int axis_for_usage_GD(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;
}

static int axis_for_usage_Sim(int usage)
{
    switch (usage)
    {
        case kHIDUsage_Sim_Rudder: return AXIS_RZ;
        case kHIDUsage_Sim_Throttle: return AXIS_Z;
        case kHIDUsage_Sim_Steering: return AXIS_X;
        case kHIDUsage_Sim_Accelerator: return AXIS_Y;
        case kHIDUsage_Sim_Brake: 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 || usage == kHIDUsage_GD_MultiAxisController))
                {
                    CFArrayAppendValue(main_elements, element);
                    total++;
                }
            }
        }
        CFRelease(elements);
    }

    TRACE("-> total %d\n", (int)total);
    return total;
}
/**************************************************************************
 *                              device_name_comparator
 *
 * Virtual joysticks may not have a kIOHIDLocationIDKey and will default to location ID of 0, this orders virtual joysticks by their name
 */
static CFComparisonResult device_name_comparator(IOHIDDeviceRef device1, IOHIDDeviceRef device2)
{
    CFStringRef name1 = copy_device_name(device1), name2 = copy_device_name(device2);
    CFComparisonResult result = CFStringCompare(name1, name2, (kCFCompareForcedOrdering | kCFCompareNumerically));
    CFRelease(name1);
    CFRelease(name2);
    return  result;
}

/**************************************************************************
 *                              device_location_name_comparator
 *
 * Helper to sort device array first by location ID, since location IDs are consistent across boots & launches, then by product name
 */
static CFComparisonResult device_location_name_comparator(const void *val1, const void *val2, void *context)
{
    IOHIDDeviceRef device1 = (IOHIDDeviceRef)val1, device2 = (IOHIDDeviceRef)val2;
    long loc1 = get_device_location_ID(device1), loc2 = get_device_location_ID(device2);

    if (loc1 < loc2)
        return kCFCompareLessThan;
    else if (loc1 > loc2)
        return kCFCompareGreaterThan;
    return device_name_comparator(device1, device2);
}

/**************************************************************************
 *                              copy_set_to_array
 *
 * Helper to copy the CFSet to a CFArray
 */
static void copy_set_to_array(const void *value, void *context)
{
    CFArrayAppendValue(context, value);
}

/**************************************************************************
 *                              find_osx_devices
 */
static int find_osx_devices(void)
{
    IOHIDManagerRef hid_manager;
    int usages[] = { kHIDUsage_GD_Joystick, kHIDUsage_GD_GamePad, kHIDUsage_GD_MultiAxisController };
    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;
        CFMutableArrayRef devices;

        num_devices = CFSetGetCount(devset);
        devices = CFArrayCreateMutable(kCFAllocatorDefault, num_devices, &kCFTypeArrayCallBacks);
        CFSetApplyFunction(devset, copy_set_to_array, (void *)devices);
        CFArraySortValues(devices, CFRangeMake(0, num_devices), device_location_name_comparator, NULL);

        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;
        uint32_t usage_page;

        child = (IOHIDElementRef)CFArrayGetValueAtIndex(children, i);
        TRACE("child %s\n", debugstr_element(child));
        type = IOHIDElementGetType(child);
        usage_page = IOHIDElementGetUsagePage(child);

        switch (type)
        {
            case kIOHIDElementTypeCollection:
                collect_joystick_elements(joystick, child);
                break;
            case kIOHIDElementTypeInput_Button:
            {
                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:
            case kIOHIDElementTypeInput_Misc:
            {
                uint32_t usage = IOHIDElementGetUsage( child );
                switch (usage_page)
                {
                    case kHIDPage_GenericDesktop:
                    {
                        switch(usage)
                        {
                            case kHIDUsage_GD_Hatswitch:
                            {
                                TRACE("kIOHIDElementTypeInput_Axis/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_GD(usage);
                                TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%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:
                            case kHIDUsage_GD_Dial:
                            case kHIDUsage_GD_Wheel:
                            {
                                /* if one axis is taken, fall to the next until axes are filled */
                                int possible_axes[3] = {AXIS_Z,AXIS_RY,AXIS_RX};
                                int axis = 0;
                                while(axis < 3 && joystick->axes[possible_axes[axis]].element)
                                    axis++;
                                if (axis == 3)
                                    TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d)\n    ignoring\n", usage);
                                else
                                {
                                    TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d) axis %d\n", usage, possible_axes[axis]);
                                    joystick->axes[possible_axes[axis]].element = (IOHIDElementRef)CFRetain(child);
                                    joystick->axes[possible_axes[axis]].min_value = IOHIDElementGetLogicalMin(child);
                                    joystick->axes[possible_axes[axis]].max_value = IOHIDElementGetLogicalMax(child);
                                }
                                break;
                            }
                            default:
                                FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled GD Page usage %d\n", usage);
                                break;
                        }
                        break;
                    }
                    case kHIDPage_Simulation:
                    {
                        switch(usage)
                        {
                            case kHIDUsage_Sim_Rudder:
                            case kHIDUsage_Sim_Throttle:
                            case kHIDUsage_Sim_Steering:
                            case kHIDUsage_Sim_Accelerator:
                            case kHIDUsage_Sim_Brake:
                            {
                                int axis = axis_for_usage_Sim(usage);
                                TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_Sim_<axis> (%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;
                            }
                            default:
                                FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled Sim Page usage %d\n", usage);
                                break;
                        }
                        break;
                    }
                    default:
                        FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled Usage Page %d\n", usage_page);
                        break;
                }
                break;
            }
            case kIOHIDElementTypeFeature:
                /* Describes input and output elements not intended for consumption by the end user. Ignoring. */
                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_HASV; break;
                    case AXIS_RY: caps->wCaps |= JOYCAPS_HASU; 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;
}

/*
 * Helper to get the value from an element
 */
static LRESULT driver_getElementValue(IOHIDDeviceRef device, IOHIDElementRef element, IOHIDValueRef *pValueRef)
{
    IOReturn ret;
    ret = IOHIDDeviceGetValue(device, element, pValueRef);
    switch (ret)
    {
        case kIOReturnSuccess:
            return JOYERR_NOERROR;
        case kIOReturnNotAttached:
            return JOYERR_UNPLUGGED;
        default:
            ERR("IOHIDDeviceGetValue returned 0x%x\n",ret);
            return JOYERR_NOCANDO;
    }
}

/**************************************************************************
 *                              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_RETURNV, FIELD_OFFSET(JOYINFOEX, dwVpos) },
        { JOY_RETURNU, FIELD_OFFSET(JOYINFOEX, dwUpos) },
        { JOY_RETURNR, FIELD_OFFSET(JOYINFOEX, dwRpos) },
    };

    joystick_t* joystick;
    IOHIDDeviceRef device;
    CFIndex i, count;
    IOHIDValueRef valueRef;
    long value;
    LRESULT rc;

    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);
            rc = driver_getElementValue(device, button, &valueRef);
            if (rc != JOYERR_NOERROR)
                return rc;
            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)
            {
                rc = driver_getElementValue(device, joystick->axes[i].element, &valueRef);
                if (rc != JOYERR_NOERROR)
                    return rc;
                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)
        {
            rc = driver_getElementValue(device, joystick->hatswitch, &valueRef);
            if (rc != JOYERR_NOERROR)
                return rc;
            value = IOHIDValueGetIntegerValue(valueRef);
            if (value >= 8)
                info->dwPOV = JOY_POVCENTERED;
            else
                info->dwPOV = value * 4500;
        }
        else
        {
            info->dwPOV = JOY_POVCENTERED;
            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 */
