/*
 * 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 <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,
    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("<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 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_<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:
                        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 */
