/*		DirectInput Joystick device
 *
 * Copyright 1998 Marcus Meissner
 * Copyright 1998,1999 Lionel Ulmer
 * Copyright 2000-2001 TransGaming Technologies 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * To Do:
 *	dead zone
 *	force feedback
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/fcntl.h>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#include <errno.h>
#ifdef HAVE_SYS_ERRNO_H
# include <sys/errno.h>
#endif
#ifdef HAVE_LINUX_IOCTL_H
# include <linux/ioctl.h>
#endif
#ifdef HAVE_LINUX_JOYSTICK_H
# include <linux/joystick.h>
#endif

#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"

WINE_DEFAULT_DEBUG_CHANNEL(dinput);

#ifdef HAVE_LINUX_22_JOYSTICK_API

#define JOYDEV "/dev/js"

typedef struct {
    LONG lMin;
    LONG lMax;
    LONG lDeadZone;
    LONG lSaturation;
} ObjProps;

typedef struct {
    LONG lX;
    LONG lY;
} POV;

typedef struct JoystickImpl JoystickImpl;
static const IDirectInputDevice8AVtbl JoystickAvt;
static const IDirectInputDevice8WVtbl JoystickWvt;
struct JoystickImpl
{
        const void                     *lpVtbl;
        DWORD                           ref;
        GUID                            guid;
	char				dev[32];

	/* The 'parent' DInput */
	IDirectInputImpl               *dinput;

	/* joystick private */
	int				joyfd;
	DIJOYSTATE2			js;		/* wine data */
	LPDIDATAFORMAT			user_df;	/* user defined format */
	DataFormat			*transform;	/* wine to user format converter */
	int				*offsets;	/* object offsets */
	ObjProps			*props;
        HANDLE				hEvent;
        LPDIDEVICEOBJECTDATA 		data_queue;
        int				queue_head, queue_tail, queue_len;
	BOOL				acquired;
	char				*name;
	DIDEVCAPS			devcaps;
	LONG				deadzone;
	int				*axis_map;
	int				axes;
	int				buttons;
	POV				povs[4];
	CRITICAL_SECTION		crit;
	BOOL				overflow;
};

static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
  0x9e573ed9,
  0x7734,
  0x11d2,
  {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
};

static void _dump_DIDEVCAPS(LPDIDEVCAPS lpDIDevCaps)
{
    TRACE("dwSize: %ld\n", lpDIDevCaps->dwSize);
    TRACE("dwFlags: %08lx\n",lpDIDevCaps->dwFlags);
    TRACE("dwDevType: %08lx %s\n", lpDIDevCaps->dwDevType,
          lpDIDevCaps->dwDevType == DIDEVTYPE_DEVICE ? "DIDEVTYPE_DEVICE" :
          lpDIDevCaps->dwDevType == DIDEVTYPE_DEVICE ? "DIDEVTYPE_DEVICE" :
          lpDIDevCaps->dwDevType == DIDEVTYPE_MOUSE ? "DIDEVTYPE_MOUSE" :
          lpDIDevCaps->dwDevType == DIDEVTYPE_KEYBOARD ? "DIDEVTYPE_KEYBOARD" :
          lpDIDevCaps->dwDevType == DIDEVTYPE_JOYSTICK ? "DIDEVTYPE_JOYSTICK" :
          lpDIDevCaps->dwDevType == DIDEVTYPE_HID ? "DIDEVTYPE_HID" : "UNKNOWN");
    TRACE("dwAxes: %ld\n",lpDIDevCaps->dwAxes);
    TRACE("dwButtons: %ld\n",lpDIDevCaps->dwButtons);
    TRACE("dwPOVs: %ld\n",lpDIDevCaps->dwPOVs);
    if (lpDIDevCaps->dwSize > sizeof(DIDEVCAPS_DX3)) {
        TRACE("dwFFSamplePeriod: %ld\n",lpDIDevCaps->dwFFSamplePeriod);
        TRACE("dwFFMinTimeResolution: %ld\n",lpDIDevCaps->dwFFMinTimeResolution);
        TRACE("dwFirmwareRevision: %ld\n",lpDIDevCaps->dwFirmwareRevision);
        TRACE("dwHardwareRevision: %ld\n",lpDIDevCaps->dwHardwareRevision);
        TRACE("dwFFDriverVersion: %ld\n",lpDIDevCaps->dwFFDriverVersion);
    }
}

static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
{
    int fd = -1;
    char dev[32];

    if (dwFlags & DIEDFL_FORCEFEEDBACK) {
        WARN("force feedback not supported\n");
        return FALSE;
    }

    if ((dwDevType == 0) ||
	((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
	(((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
        /* check whether we have a joystick */
        sprintf(dev, "%s%d", JOYDEV, id);
        if ((fd = open(dev,O_RDONLY)) < 0) {
            WARN("open(%s,O_RDONLY) failed: %s\n", dev, strerror(errno));
            return FALSE;
        }

        /* Return joystick */
        lpddi->guidInstance = DInput_Wine_Joystick_GUID;
        lpddi->guidInstance.Data3 = id;
        lpddi->guidProduct = DInput_Wine_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);
#if defined(JSIOCGNAME)
        if (ioctl(fd,JSIOCGNAME(sizeof(lpddi->tszProductName)),lpddi->tszProductName) < 0) {
            WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", dev, strerror(errno));
            strcpy(lpddi->tszProductName, "Wine Joystick");
        }
#else
        strcpy(lpddi->tszProductName, "Wine Joystick");
#endif

        lpddi->guidFFDriver = GUID_NULL;
        close(fd);
        TRACE("Enumerating the linux Joystick device: %s (%s)\n", dev, lpddi->tszProductName);
        return TRUE;
    }

    return FALSE;
}

static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
{
    int fd = -1;
    char name[MAX_PATH];
    char dev[32];
    char friendly[32];

    if (dwFlags & DIEDFL_FORCEFEEDBACK) {
        WARN("force feedback not supported\n");
        return FALSE;
    }

    if ((dwDevType == 0) ||
	((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
	(((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
        /* check whether we have a joystick */
        sprintf(dev, "%s%d", JOYDEV, id);
        if ((fd = open(dev,O_RDONLY)) < 0) {
            WARN("open(%s,O_RDONLY) failed: %s\n", dev, strerror(errno));
            return FALSE;
        }

        /* Return joystick */
        lpddi->guidInstance = DInput_Wine_Joystick_GUID;
        lpddi->guidInstance.Data3 = id;
        lpddi->guidProduct = DInput_Wine_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);
#if defined(JSIOCGNAME)
        if (ioctl(fd,JSIOCGNAME(sizeof(name)),name) < 0) {
            WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", dev, strerror(errno));
            strcpy(name, "Wine Joystick");
        }
#else
        strcpy(name, "Wine Joystick");
#endif
        MultiByteToWideChar(CP_ACP, 0, name, -1, lpddi->tszProductName, MAX_PATH);
        lpddi->guidFFDriver = GUID_NULL;
        close(fd);
        TRACE("Enumerating the linux Joystick device: %s (%s)\n",dev,name);
        return TRUE;
    }

    return FALSE;
}

/*
 * Get a config key from either the app-specific or the default config
 */

inline static DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
                                    char *buffer, DWORD size )
{
    if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, buffer, &size ))
        return 0;

    if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, buffer, &size ))
        return 0;

    return ERROR_FILE_NOT_FOUND;
}

/*
 * Setup the dinput options.
 */

static HRESULT setup_dinput_options(JoystickImpl * device)
{
    char buffer[MAX_PATH+16];
    HKEY hkey, appkey = 0;
    DWORD len;

    buffer[MAX_PATH]='\0';

    /* @@ Wine registry key: HKCU\Software\Wine\DirectInput */
    if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\DirectInput", &hkey)) hkey = 0;

    len = GetModuleFileNameA( 0, buffer, MAX_PATH );
    if (len && len < MAX_PATH) {
        HKEY tmpkey;
        /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DirectInput */
        if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
        {
            char *p, *appname = buffer;
            if ((p = strrchr( appname, '/' ))) appname = p + 1;
            if ((p = strrchr( appname, '\\' ))) appname = p + 1;
            strcat( appname, "\\DirectInput" );
            if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
            RegCloseKey( tmpkey );
        }
    }

    /* get options */

    if (!get_config_key( hkey, appkey, "DefaultDeadZone", buffer, MAX_PATH )) {
        device->deadzone = atoi(buffer);
        TRACE("setting default deadzone to: \"%s\" %ld\n", buffer, device->deadzone);
    }

    if (!get_config_key( hkey, appkey, device->name, buffer, MAX_PATH )) {
        int tokens = 0;
        int axis = 0;
        int pov = 0;
        const char *delim = ",";
        char * ptr;
        TRACE("\"%s\" = \"%s\"\n", device->name, buffer);

        device->axis_map = HeapAlloc(GetProcessHeap(), 0, device->axes * sizeof(int));
        if (device->axis_map == 0)
            return DIERR_OUTOFMEMORY;

        if ((ptr = strtok(buffer, delim)) != NULL) {
            do {
                if (strcmp(ptr, "X") == 0) {
                    device->axis_map[tokens] = 0;
                    axis++;
                } else if (strcmp(ptr, "Y") == 0) {
                    device->axis_map[tokens] = 1;
                    axis++;
                } else if (strcmp(ptr, "Z") == 0) {
                    device->axis_map[tokens] = 2;
                    axis++;
                } else if (strcmp(ptr, "Rx") == 0) {
                    device->axis_map[tokens] = 3;
                    axis++;
                } else if (strcmp(ptr, "Ry") == 0) {
                    device->axis_map[tokens] = 4;
                    axis++;
                } else if (strcmp(ptr, "Rz") == 0) {
                    device->axis_map[tokens] = 5;
                    axis++;
                } else if (strcmp(ptr, "Slider1") == 0) {
                    device->axis_map[tokens] = 6;
                    axis++;
                } else if (strcmp(ptr, "Slider2") == 0) {
                    device->axis_map[tokens] = 7;
                    axis++;
                } else if (strcmp(ptr, "POV1") == 0) {
                    device->axis_map[tokens++] = 8;
                    device->axis_map[tokens] = 8;
                    pov++;
                } else if (strcmp(ptr, "POV2") == 0) {
                    device->axis_map[tokens++] = 9;
                    device->axis_map[tokens] = 9;
                    pov++;
                } else if (strcmp(ptr, "POV3") == 0) {
                    device->axis_map[tokens++] = 10;
                    device->axis_map[tokens] = 10;
                    pov++;
                } else if (strcmp(ptr, "POV4") == 0) {
                    device->axis_map[tokens++] = 11;
                    device->axis_map[tokens] = 11;
                    pov++;
                } else {
                    ERR("invalid joystick axis type: %s\n", ptr);
                    device->axis_map[tokens] = tokens;
                    axis++;
                }

                tokens++;
            } while ((ptr = strtok(NULL, delim)) != NULL);

            if (tokens != device->devcaps.dwAxes) {
                ERR("not all joystick axes mapped: %d axes(%d,%d), %d arguments\n", device->axes, axis, pov,tokens);
                while (tokens < device->axes) {
                    device->axis_map[tokens] = tokens;
                    tokens++;
                }
            }
        }

        device->devcaps.dwAxes = axis;
        device->devcaps.dwPOVs = pov;
    }

    if (appkey)
        RegCloseKey( appkey );

    if (hkey)
        RegCloseKey( hkey );

    return DI_OK;
}

void calculate_ids(JoystickImpl* device)
{
    int i;
    int axis = 0;
    int button = 0;
    int pov = 0;
    int axis_base;
    int pov_base;
    int button_base;

    /* Make two passes over the format. The first counts the number
     * for each type and the second sets the id */
    for (i = 0; i < device->user_df->dwNumObjs; i++) {
        if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_AXIS)
            axis++;
        else if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_POV)
            pov++;
        else if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_BUTTON)
            button++;
    }

    axis_base = 0;
    pov_base = axis;
    button_base = axis + pov;

    axis = 0;
    button = 0;
    pov = 0;

    for (i = 0; i < device->user_df->dwNumObjs; i++) {
        DWORD type = 0;
        if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_AXIS) {
            axis++;
            type = DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) |
                DIDFT_MAKEINSTANCE(axis + axis_base);
            TRACE("axis type = 0x%08lx\n", type);
        } else if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_POV) {
            pov++;
            type = DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) |
                DIDFT_MAKEINSTANCE(pov + pov_base);
            TRACE("POV type = 0x%08lx\n", type);
        } else if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_BUTTON) {
            button++;
            type = DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) |
                DIDFT_MAKEINSTANCE(button + button_base);
            TRACE("button type = 0x%08lx\n", type);
        }
        device->user_df->rgodf[i].dwType = type;
    }
}

static HRESULT alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput, LPDIRECTINPUTDEVICEA* pdev)
{
    DWORD i;
    JoystickImpl* newDevice;
    char name[MAX_PATH];
    HRESULT hr;

    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
    if (newDevice == 0) {
        WARN("out of memory\n");
        *pdev = 0;
        return DIERR_OUTOFMEMORY;
    }

    sprintf(newDevice->dev, "%s%d", JOYDEV, rguid->Data3);

    if ((newDevice->joyfd = open(newDevice->dev,O_RDONLY)) < 0) {
        WARN("open(%s,O_RDONLY) failed: %s\n", newDevice->dev, strerror(errno));
        HeapFree(GetProcessHeap(), 0, newDevice);
        return DIERR_DEVICENOTREG;
    }

    /* get the device name */
#if defined(JSIOCGNAME)
    if (ioctl(newDevice->joyfd,JSIOCGNAME(MAX_PATH),name) < 0) {
        WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", newDevice->dev, strerror(errno));
        strcpy(name, "Wine Joystick");
    }
#else
    strcpy(name, "Wine Joystick");
#endif

    /* copy the device name */
    newDevice->name = HeapAlloc(GetProcessHeap(),0,strlen(name) + 1);
    strcpy(newDevice->name, name);

#ifdef JSIOCGAXES
    if (ioctl(newDevice->joyfd,JSIOCGAXES,&newDevice->axes) < 0) {
        WARN("ioctl(%s,JSIOCGAXES) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno));
        newDevice->axes = 2;
    }
#endif
#ifdef JSIOCGBUTTONS
    if (ioctl(newDevice->joyfd,JSIOCGBUTTONS,&newDevice->buttons) < 0) {
        WARN("ioctl(%s,JSIOCGBUTTONS) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno));
        newDevice->buttons = 2;
    }
#endif

    newDevice->lpVtbl = jvt;
    newDevice->ref = 1;
    newDevice->dinput = dinput;
    newDevice->acquired = FALSE;
    newDevice->overflow = FALSE;
    CopyMemory(&(newDevice->guid),rguid,sizeof(*rguid));

    /* setup_dinput_options may change these */
    newDevice->deadzone = 5000;
    newDevice->devcaps.dwButtons = newDevice->buttons;
    newDevice->devcaps.dwAxes = newDevice->axes;
    newDevice->devcaps.dwPOVs = 0;

    /* do any user specified configuration */
    hr = setup_dinput_options(newDevice);
    if (hr != DI_OK)
        goto FAILED1;

    if (newDevice->axis_map == 0) {
        newDevice->axis_map = HeapAlloc(GetProcessHeap(), 0, newDevice->axes * sizeof(int));
        if (newDevice->axis_map == 0)
            goto FAILED;

        for (i = 0; i < newDevice->axes; i++)
            newDevice->axis_map[i] = i;
    }

    /* wine uses DIJOYSTATE2 as it's internal format so copy
     * the already defined format c_dfDIJoystick2 */
    newDevice->user_df = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwSize);
    if (newDevice->user_df == 0)
        goto FAILED;

    CopyMemory(newDevice->user_df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);

    /* copy default objects */
    newDevice->user_df->rgodf = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwNumObjs*c_dfDIJoystick2.dwObjSize);
    if (newDevice->user_df->rgodf == 0)
        goto FAILED;

    CopyMemory(newDevice->user_df->rgodf,c_dfDIJoystick2.rgodf,c_dfDIJoystick2.dwNumObjs*c_dfDIJoystick2.dwObjSize);

    /* create default properties */
    newDevice->props = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwNumObjs*sizeof(ObjProps));
    if (newDevice->props == 0)
        goto FAILED;

    /* initialize default properties */
    for (i = 0; i < c_dfDIJoystick2.dwNumObjs; i++) {
        newDevice->props[i].lMin = 0;
        newDevice->props[i].lMax = 0xffff;
        newDevice->props[i].lDeadZone = newDevice->deadzone;	/* % * 1000 */
        newDevice->props[i].lSaturation = 0;
    }

    /* create an offsets array */
    newDevice->offsets = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,c_dfDIJoystick2.dwNumObjs*sizeof(int));
    if (newDevice->offsets == 0)
        goto FAILED;

    /* create the default transform filter */
    newDevice->transform = create_DataFormat(&c_dfDIJoystick2, newDevice->user_df, newDevice->offsets);

    calculate_ids(newDevice);

    IDirectInputDevice_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->dinput);
    InitializeCriticalSection(&(newDevice->crit));
    newDevice->crit.DebugInfo->Spare[1] = (DWORD)"DINPUT_Mouse";

    newDevice->devcaps.dwSize = sizeof(newDevice->devcaps);
    newDevice->devcaps.dwFlags = DIDC_ATTACHED;
    if (newDevice->dinput->dwVersion >= 0x0800)
        newDevice->devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
    else
        newDevice->devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
    newDevice->devcaps.dwFFSamplePeriod = 0;
    newDevice->devcaps.dwFFMinTimeResolution = 0;
    newDevice->devcaps.dwFirmwareRevision = 0;
    newDevice->devcaps.dwHardwareRevision = 0;
    newDevice->devcaps.dwFFDriverVersion = 0;

    if (TRACE_ON(dinput)) {
        _dump_DIDATAFORMAT(newDevice->user_df);
       for (i = 0; i < (newDevice->axes); i++)
           TRACE("axis_map[%ld] = %d\n", i, newDevice->axis_map[i]);
        _dump_DIDEVCAPS(&newDevice->devcaps);
    }

    *pdev = (LPDIRECTINPUTDEVICEA)newDevice;

    return DI_OK;

FAILED:
    hr = DIERR_OUTOFMEMORY;
FAILED1:
    HeapFree(GetProcessHeap(),0,newDevice->axis_map);
    HeapFree(GetProcessHeap(),0,newDevice->name);
    HeapFree(GetProcessHeap(),0,newDevice->props);
    HeapFree(GetProcessHeap(),0,newDevice->user_df->rgodf);
    HeapFree(GetProcessHeap(),0,newDevice->user_df);
    HeapFree(GetProcessHeap(),0,newDevice);
    *pdev = 0;

    return hr;
}

static BOOL IsJoystickGUID(REFGUID guid)
{
    GUID wine_joystick = DInput_Wine_Joystick_GUID;
    GUID dev_guid = *guid;

    wine_joystick.Data3 = 0;
    dev_guid.Data3 = 0;

    return IsEqualGUID(&wine_joystick, &dev_guid);
}

static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
{
  if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
      (IsJoystickGUID(rguid))) {
    if ((riid == NULL) ||
	IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
	IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
	IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
	IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
      return alloc_device(rguid, &JoystickAvt, dinput, pdev);
    } else {
      WARN("no interface\n");
      *pdev = 0;
      return DIERR_NOINTERFACE;
    }
  }

  WARN("invalid device GUID\n");
  *pdev = 0;
  return DIERR_DEVICENOTREG;
}

static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
{
  if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
      (IsJoystickGUID(rguid))) {
    if ((riid == NULL) ||
	IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
	IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
	IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
	IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
      return alloc_device(rguid, &JoystickWvt, dinput, (LPDIRECTINPUTDEVICEA *)pdev);
    } else {
      WARN("no interface\n");
      *pdev = 0;
      return DIERR_NOINTERFACE;
    }
  }

  WARN("invalid device GUID\n");
  *pdev = 0;
  return DIERR_DEVICENOTREG;
}

const struct dinput_device joystick_linux_device = {
  "Wine Linux joystick driver",
  joydev_enum_deviceA,
  joydev_enum_deviceW,
  joydev_create_deviceA,
  joydev_create_deviceW
};

/******************************************************************************
 *	Joystick
 */
static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
{
    JoystickImpl *This = (JoystickImpl *)iface;
    ULONG ref;

    ref = InterlockedDecrement((&This->ref));
    if (ref)
        return ref;

    /* Free the device name */
    HeapFree(GetProcessHeap(),0,This->name);

    /* Free the axis map */
    HeapFree(GetProcessHeap(),0,This->axis_map);

    /* Free the data queue */
    HeapFree(GetProcessHeap(),0,This->data_queue);

    /* Free the DataFormat */
    HeapFree(GetProcessHeap(), 0, This->user_df->rgodf);
    HeapFree(GetProcessHeap(), 0, This->user_df);

    /* Free the properties */
    HeapFree(GetProcessHeap(), 0, This->props);

    /* Free the offsets array */
    HeapFree(GetProcessHeap(),0,This->offsets);

    /* release the data transform filter */
    release_DataFormat(This->transform);

    This->crit.DebugInfo->Spare[1] = 0;
    DeleteCriticalSection(&(This->crit));
    IDirectInputDevice_Release((LPDIRECTINPUTDEVICE8A)This->dinput);

    HeapFree(GetProcessHeap(),0,This);
    return 0;
}

/******************************************************************************
  *   SetDataFormat : the application can choose the format of the data
  *   the device driver sends back with GetDeviceState.
  */
static HRESULT WINAPI JoystickAImpl_SetDataFormat(
    LPDIRECTINPUTDEVICE8A iface,
    LPCDIDATAFORMAT df)
{
    JoystickImpl *This = (JoystickImpl *)iface;
    unsigned int i;
    LPDIDATAFORMAT new_df = 0;
    LPDIOBJECTDATAFORMAT new_rgodf = 0;
    ObjProps * new_props = 0;

    TRACE("(%p,%p)\n",This,df);

    if (df == NULL) {
        WARN("invalid pointer\n");
        return E_POINTER;
    }

    if (df->dwSize != sizeof(*df)) {
        WARN("invalid argument\n");
        return DIERR_INVALIDPARAM;
    }

    if (This->acquired) {
        WARN("acquired\n");
        return DIERR_ACQUIRED;
    }

    if (TRACE_ON(dinput))
        _dump_DIDATAFORMAT(df);

    /* Store the new data format */
    new_df = HeapAlloc(GetProcessHeap(),0,df->dwSize);
    if (new_df == 0)
        goto FAILED;

    new_rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize);
    if (new_rgodf == 0)
        goto FAILED;

    new_props = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*sizeof(ObjProps));
    if (new_props == 0)
        goto FAILED;

    HeapFree(GetProcessHeap(),0,This->user_df);
    HeapFree(GetProcessHeap(),0,This->user_df->rgodf);
    HeapFree(GetProcessHeap(),0,This->props);
    release_DataFormat(This->transform);

    This->user_df = new_df;
    CopyMemory(This->user_df, df, df->dwSize);
    This->user_df->rgodf = new_rgodf;
    CopyMemory(This->user_df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize);
    This->props = new_props;
    for (i = 0; i < df->dwNumObjs; i++) {
        This->props[i].lMin = 0;
        This->props[i].lMax = 0xffff;
        This->props[i].lDeadZone = 1000;
        This->props[i].lSaturation = 0;
    }
    This->transform = create_DataFormat(&c_dfDIJoystick2, This->user_df, This->offsets);

    calculate_ids(This);

    return DI_OK;

FAILED:
    WARN("out of memory\n");
    HeapFree(GetProcessHeap(),0,new_props);
    HeapFree(GetProcessHeap(),0,new_rgodf);
    HeapFree(GetProcessHeap(),0,new_df);
    return DIERR_OUTOFMEMORY;
}

/******************************************************************************
  *     Acquire : gets exclusive control of the joystick
  */
static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
{
    JoystickImpl *This = (JoystickImpl *)iface;

    TRACE("(%p)\n",This);

    if (This->acquired) {
        WARN("already acquired\n");
        return S_FALSE;
    }

    /* open the joystick device */
    if (This->joyfd==-1) {
        TRACE("opening joystick device %s\n", This->dev);

        This->joyfd=open(This->dev,O_RDONLY);
        if (This->joyfd==-1) {
            ERR("open(%s) failed: %s\n", This->dev, strerror(errno));
            return DIERR_NOTFOUND;
        }
    }

    This->acquired = TRUE;

    return DI_OK;
}

/******************************************************************************
  *     Unacquire : frees the joystick
  */
static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
{
    JoystickImpl *This = (JoystickImpl *)iface;

    TRACE("(%p)\n",This);

    if (!This->acquired) {
        WARN("not acquired\n");
        return DIERR_NOTACQUIRED;
    }

    if (This->joyfd!=-1) {
        TRACE("closing joystick device\n");
        close(This->joyfd);
        This->joyfd = -1;
        This->acquired = FALSE;
        return DI_OK;
    }

    This->acquired = FALSE;

    return DI_NOEFFECT;
}

LONG map_axis(JoystickImpl * This, short val, short index)
{
    double    fval = val;
    double    fmin = This->props[index].lMin;
    double    fmax = This->props[index].lMax;
    double    fret;

    fret = (((fval + 32767.0) * (fmax - fmin)) / (32767.0*2.0)) + fmin;

    if (fret >= 0.0)
        fret += 0.5;
    else
        fret -= 0.5;

    return fret;
}

/* convert wine format offset to user format object index */
int offset_to_object(JoystickImpl *This, int offset)
{
    int i;

    for (i = 0; i < This->user_df->dwNumObjs; i++) {
        if (This->user_df->rgodf[i].dwOfs == offset)
            return i;
    }

    return -1;
}

static LONG calculate_pov(JoystickImpl *This, int index)
{
    if (This->povs[index].lX < 16384) {
        if (This->povs[index].lY < 16384)
            This->js.rgdwPOV[index] = 31500;
        else if (This->povs[index].lY > 49150)
            This->js.rgdwPOV[index] = 22500;
        else
            This->js.rgdwPOV[index] = 27000;
    } else if (This->povs[index].lX > 49150) {
        if (This->povs[index].lY < 16384)
            This->js.rgdwPOV[index] = 4500;
        else if (This->povs[index].lY > 49150)
            This->js.rgdwPOV[index] = 13500;
        else
            This->js.rgdwPOV[index] = 9000;
    } else {
        if (This->povs[index].lY < 16384)
            This->js.rgdwPOV[index] = 0;
        else if (This->povs[index].lY > 49150)
            This->js.rgdwPOV[index] = 18000;
        else
            This->js.rgdwPOV[index] = -1;
    }

    return This->js.rgdwPOV[index];
}

static void joy_polldev(JoystickImpl *This) {
    struct timeval tv;
    fd_set	readfds;
    struct	js_event jse;
    TRACE("(%p)\n", This);

    if (This->joyfd==-1) {
        WARN("no device\n");
        return;
    }
    while (1) {
	memset(&tv,0,sizeof(tv));
	FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds);
	if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv))
	    return;
	/* we have one event, so we can read */
	if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
	    return;
	}
        TRACE("js_event: type 0x%x, number %d, value %d\n",
              jse.type,jse.number,jse.value);
        if (jse.type & JS_EVENT_BUTTON) {
            int offset = This->offsets[jse.number + 12];
            int value = jse.value?0x80:0x00;

            This->js.rgbButtons[jse.number] = value;
            GEN_EVENT(offset,value,jse.time,(This->dinput->evsequence)++);
        } else if (jse.type & JS_EVENT_AXIS) {
            int number = This->axis_map[jse.number];	/* wine format object index */
            if (number < 12) {
                int offset = This->offsets[number];
                int index = offset_to_object(This, offset);
                LONG value = map_axis(This, jse.value, index);

                /* FIXME do deadzone and saturation here */

                TRACE("changing axis %d => %d\n", jse.number, number);
                switch (number) {
                case 0:
                    This->js.lX = value;
                    break;
                case 1:
                    This->js.lY = value;
                    break;
                case 2:
                    This->js.lZ = value;
                    break;
                case 3:
                    This->js.lRx = value;
                    break;
                case 4:
                    This->js.lRy = value;
                    break;
                case 5:
                    This->js.lRz = value;
                    break;
                case 6:
                    This->js.rglSlider[0] = value;
                    break;
                case 7:
                    This->js.rglSlider[1] = value;
                    break;
                case 8:
                    /* FIXME don't go off array */
                    if (This->axis_map[jse.number + 1] == number)
                        This->povs[0].lX = value;
                    else if (This->axis_map[jse.number - 1] == number)
                        This->povs[0].lY = value;
                    value = calculate_pov(This, 0);
                    break;
                case 9:
                    if (This->axis_map[jse.number + 1] == number)
                        This->povs[1].lX = value;
                    else if (This->axis_map[jse.number - 1] == number)
                        This->povs[1].lY = value;
                    value = calculate_pov(This, 1);
                    break;
                case 10:
                    if (This->axis_map[jse.number + 1] == number)
                        This->povs[2].lX = value;
                    else if (This->axis_map[jse.number - 1] == number)
                        This->povs[2].lY = value;
                    value = calculate_pov(This, 2);
                    break;
                case 11:
                    if (This->axis_map[jse.number + 1] == number)
                        This->povs[3].lX = value;
                    else if (This->axis_map[jse.number - 1] == number)
                        This->povs[3].lY = value;
                    value = calculate_pov(This, 3);
                    break;
                }

                GEN_EVENT(offset,value,jse.time,(This->dinput->evsequence)++);
            } else
                WARN("axis %d not supported\n", number);
        }
    }
}

/******************************************************************************
  *     GetDeviceState : returns the "state" of the joystick.
  *
  */
static HRESULT WINAPI JoystickAImpl_GetDeviceState(
    LPDIRECTINPUTDEVICE8A iface,
    DWORD len,
    LPVOID ptr)
{
    JoystickImpl *This = (JoystickImpl *)iface;

    TRACE("(%p,0x%08lx,%p)\n",This,len,ptr);

    if (!This->acquired) {
        WARN("not acquired\n");
        return DIERR_NOTACQUIRED;
    }

    /* update joystick state */
    joy_polldev(This);

    /* convert and copy data to user supplied buffer */
    fill_DataFormat(ptr, &This->js, This->transform);

    return DI_OK;
}

/******************************************************************************
  *     GetDeviceData : gets buffered input data.
  */
static HRESULT WINAPI JoystickAImpl_GetDeviceData(
    LPDIRECTINPUTDEVICE8A iface,
    DWORD dodsize,
    LPDIDEVICEOBJECTDATA dod,
    LPDWORD entries,
    DWORD flags)
{
    JoystickImpl *This = (JoystickImpl *)iface;
    DWORD len;
    int nqtail;
    HRESULT hr = DI_OK;

    TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);

    if (!This->acquired) {
        WARN("not acquired\n");
        return DIERR_NOTACQUIRED;
    }

    EnterCriticalSection(&(This->crit));

    joy_polldev(This);

    len = ((This->queue_head < This->queue_tail) ? This->queue_len : 0)
        + (This->queue_head - This->queue_tail);
    if (len > *entries)
        len = *entries;

    if (dod == NULL) {
        if (len)
            TRACE("Application discarding %ld event(s).\n", len);

        *entries = len;
        nqtail = This->queue_tail + len;
        while (nqtail >= This->queue_len)
            nqtail -= This->queue_len;
    } else {
        if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3)) {
            ERR("Wrong structure size !\n");
            LeaveCriticalSection(&(This->crit));
            return DIERR_INVALIDPARAM;
        }

        if (len)
            TRACE("Application retrieving %ld event(s).\n", len);

        *entries = 0;
        nqtail = This->queue_tail;
        while (len) {
            /* Copy the buffered data into the application queue */
            memcpy((char *)dod + *entries * dodsize, This->data_queue + nqtail, dodsize);
            /* Advance position */
            nqtail++;
            if (nqtail >= This->queue_len)
                nqtail -= This->queue_len;
            (*entries)++;
            len--;
        }
    }

    if (This->overflow) {
        hr = DI_BUFFEROVERFLOW;
        if (!(flags & DIGDD_PEEK)) {
            This->overflow = FALSE;
        }
    }

    if (!(flags & DIGDD_PEEK))
        This->queue_tail = nqtail;

    LeaveCriticalSection(&(This->crit));

    return hr;
}

int find_property(JoystickImpl * This, LPCDIPROPHEADER ph)
{
    int i;
    if (ph->dwHow == DIPH_BYOFFSET) {
        return offset_to_object(This, ph->dwObj);
    } else if (ph->dwHow == DIPH_BYID) {
        for (i = 0; i < This->user_df->dwNumObjs; i++) {
            if ((This->user_df->rgodf[i].dwType & 0x00ffffff) == (ph->dwObj & 0x00ffffff)) {
                return i;
            }
        }
    }

    return -1;
}

/******************************************************************************
  *     SetProperty : change input device properties
  */
static HRESULT WINAPI JoystickAImpl_SetProperty(
    LPDIRECTINPUTDEVICE8A iface,
    REFGUID rguid,
    LPCDIPROPHEADER ph)
{
    JoystickImpl *This = (JoystickImpl *)iface;
    int i;

    TRACE("(%p,%s,%p)\n",This,debugstr_guid(rguid),ph);

    if (ph == NULL) {
        WARN("invalid parameter: ph == NULL\n");
        return DIERR_INVALIDPARAM;
    }

    if (TRACE_ON(dinput))
        _dump_DIPROPHEADER(ph);

    if (!HIWORD(rguid)) {
        switch ((DWORD)rguid) {
        case (DWORD) DIPROP_BUFFERSIZE: {
            LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
            TRACE("buffersize = %ld\n",pd->dwData);
            if (This->data_queue)
                This->data_queue = HeapReAlloc(GetProcessHeap(),0, This->data_queue, pd->dwData * sizeof(DIDEVICEOBJECTDATA));
            else
                This->data_queue = HeapAlloc(GetProcessHeap(),0, pd->dwData * sizeof(DIDEVICEOBJECTDATA));
            This->queue_head = 0;
            This->queue_tail = 0;
            This->queue_len  = pd->dwData;
            break;
        }
        case (DWORD)DIPROP_RANGE: {
            LPCDIPROPRANGE	pr = (LPCDIPROPRANGE)ph;
            if (ph->dwHow == DIPH_DEVICE) {
                TRACE("proprange(%ld,%ld) all\n",pr->lMin,pr->lMax);
                for (i = 0; i < This->user_df->dwNumObjs; i++) {
                    This->props[i].lMin = pr->lMin;
                    This->props[i].lMax = pr->lMax;
                }
            } else {
                int obj = find_property(This, ph);
                TRACE("proprange(%ld,%ld) obj=%d\n",pr->lMin,pr->lMax,obj);
                if (obj >= 0) {
                    This->props[obj].lMin = pr->lMin;
                    This->props[obj].lMax = pr->lMax;
                    return DI_OK;
                }
            }
            break;
        }
        case (DWORD)DIPROP_DEADZONE: {
            LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
            if (ph->dwHow == DIPH_DEVICE) {
                TRACE("deadzone(%ld) all\n",pd->dwData);
                for (i = 0; i < This->user_df->dwNumObjs; i++)
                    This->props[i].lDeadZone  = pd->dwData;
            } else {
                int obj = find_property(This, ph);
                TRACE("deadzone(%ld) obj=%d\n",pd->dwData,obj);
                if (obj >= 0) {
                    This->props[obj].lDeadZone  = pd->dwData;
                    return DI_OK;
                }
            }
            break;
        }
        case (DWORD)DIPROP_SATURATION: {
            LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
            if (ph->dwHow == DIPH_DEVICE) {
                TRACE("saturation(%ld) all\n",pd->dwData);
                for (i = 0; i < This->user_df->dwNumObjs; i++)
                    This->props[i].lSaturation = pd->dwData;
            } else {
                int obj = find_property(This, ph);
                TRACE("saturation(%ld) obj=%d\n",pd->dwData,obj);
                if (obj >= 0) {
                    This->props[obj].lSaturation = pd->dwData;
                    return DI_OK;
                }
            }
            break;
        }
        default:
            FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
            break;
        }
    }

    return DI_OK;
}

/******************************************************************************
  *     SetEventNotification : specifies event to be sent on state change
  */
static HRESULT WINAPI JoystickAImpl_SetEventNotification(
	LPDIRECTINPUTDEVICE8A iface, HANDLE hnd
) {
    JoystickImpl *This = (JoystickImpl *)iface;

    TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
    This->hEvent = hnd;
    return DI_OK;
}

static HRESULT WINAPI JoystickAImpl_GetCapabilities(
	LPDIRECTINPUTDEVICE8A iface,
	LPDIDEVCAPS lpDIDevCaps)
{
    JoystickImpl *This = (JoystickImpl *)iface;
    int size;

    TRACE("%p->(%p)\n",iface,lpDIDevCaps);

    if (lpDIDevCaps == NULL) {
        WARN("invalid pointer\n");
        return E_POINTER;
    }

    size = lpDIDevCaps->dwSize;

    if (!(size == sizeof(DIDEVCAPS) || size == sizeof(DIDEVCAPS_DX3))) {
        WARN("invalid parameter\n");
        return DIERR_INVALIDPARAM;
    }

    CopyMemory(lpDIDevCaps, &This->devcaps, size);
    lpDIDevCaps->dwSize = size;

    if (TRACE_ON(dinput))
        _dump_DIDEVCAPS(lpDIDevCaps);

    return DI_OK;
}

static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE8A iface)
{
    JoystickImpl *This = (JoystickImpl *)iface;

    TRACE("(%p)\n",This);

    if (!This->acquired) {
        WARN("not acquired\n");
        return DIERR_NOTACQUIRED;
    }

    joy_polldev(This);
    return DI_OK;
}

/******************************************************************************
  *     EnumObjects : enumerate the different buttons and axis...
  */
static HRESULT WINAPI JoystickAImpl_EnumObjects(
	LPDIRECTINPUTDEVICE8A iface,
	LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
	LPVOID lpvRef,
	DWORD dwFlags)
{
  JoystickImpl *This = (JoystickImpl *)iface;
  DIDEVICEOBJECTINSTANCEA ddoi;
  BYTE i;
  int user_offset;
  int user_object;

  TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags);
  if (TRACE_ON(dinput)) {
    TRACE("  - flags = ");
    _dump_EnumObjects_flags(dwFlags);
    TRACE("\n");
  }

  /* Only the fields till dwFFMaxForce are relevant */
  ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce);

  /* For the joystick, do as is done in the GetCapabilities function */
  if ((dwFlags == DIDFT_ALL) ||
      (dwFlags & DIDFT_AXIS) ||
      (dwFlags & DIDFT_POV)) {
    int	pov[4] = { 0, 0, 0, 0 };
    int axes = 0;
    int povs = 0;

    for (i = 0; i < This->axes; i++) {
      int wine_obj = This->axis_map[i];
      BOOL skip = FALSE;

      switch (wine_obj) {
      case 0:
	ddoi.guidType = GUID_XAxis;
	break;
      case 1:
	ddoi.guidType = GUID_YAxis;
	break;
      case 2:
	ddoi.guidType = GUID_ZAxis;
	break;
      case 3:
	ddoi.guidType = GUID_RxAxis;
	break;
      case 4:
	ddoi.guidType = GUID_RyAxis;
	break;
      case 5:
	ddoi.guidType = GUID_RzAxis;
	break;
      case 6:
	ddoi.guidType = GUID_Slider;
	break;
      case 7:
	ddoi.guidType = GUID_Slider;
	break;
      case 8:
        pov[0]++;
	ddoi.guidType = GUID_POV;
	break;
      case 9:
        pov[1]++;
	ddoi.guidType = GUID_POV;
	break;
      case 10:
        pov[2]++;
	ddoi.guidType = GUID_POV;
	break;
      case 11:
        pov[3]++;
	ddoi.guidType = GUID_POV;
	break;
      default:
	ddoi.guidType = GUID_Unknown;
      }
      if (wine_obj < 8) {
          user_offset = This->offsets[wine_obj];	/* get user offset from wine index */
          user_object = offset_to_object(This, user_offset);

          ddoi.dwType = This->user_df->rgodf[user_object].dwType & 0x00ffffff;
          ddoi.dwOfs =  This->user_df->rgodf[user_object].dwOfs;
          sprintf(ddoi.tszName, "Axis %d", axes);
          axes++;
      } else {
          if (pov[wine_obj - 8] < 2) {
              user_offset = This->offsets[wine_obj];	/* get user offset from wine index */
              user_object = offset_to_object(This, user_offset);

              ddoi.dwType = This->user_df->rgodf[user_object].dwType & 0x00ffffff;
              ddoi.dwOfs =  This->user_df->rgodf[user_object].dwOfs;
              sprintf(ddoi.tszName, "POV %d", povs);
              povs++;
          } else
              skip = TRUE;
      }
      if (!skip) {
          _dump_OBJECTINSTANCEA(&ddoi);
          if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE)
              return DI_OK;
      }
    }
  }

  if ((dwFlags == DIDFT_ALL) ||
      (dwFlags & DIDFT_BUTTON)) {

    /* The DInput SDK says that GUID_Button is only for mouse buttons but well... */
    ddoi.guidType = GUID_Button;

    for (i = 0; i < This->buttons; i++) {
      user_offset = This->offsets[i + 12];	/* get user offset from wine index */
      user_object = offset_to_object(This, user_offset);
      ddoi.guidType = GUID_Button;
      ddoi.dwType = This->user_df->rgodf[user_object].dwType & 0x00ffffff;
      ddoi.dwOfs =  This->user_df->rgodf[user_object].dwOfs;
      sprintf(ddoi.tszName, "Button %d", i);
      _dump_OBJECTINSTANCEA(&ddoi);
      if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
    }
  }

  return DI_OK;
}

/******************************************************************************
  *     EnumObjects : enumerate the different buttons and axis...
  */
static HRESULT WINAPI JoystickWImpl_EnumObjects(
	LPDIRECTINPUTDEVICE8W iface,
	LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
	LPVOID lpvRef,
	DWORD dwFlags)
{
  JoystickImpl *This = (JoystickImpl *)iface;

  device_enumobjects_AtoWcb_data data;

  data.lpCallBack = lpCallback;
  data.lpvRef = lpvRef;

  return JoystickAImpl_EnumObjects((LPDIRECTINPUTDEVICE8A) This, (LPDIENUMDEVICEOBJECTSCALLBACKA) DIEnumDevicesCallbackAtoW, (LPVOID) &data, dwFlags);
}

/******************************************************************************
  *     GetProperty : get input device properties
  */
static HRESULT WINAPI JoystickAImpl_GetProperty(
    LPDIRECTINPUTDEVICE8A iface,
    REFGUID rguid,
    LPDIPROPHEADER pdiph)
{
    JoystickImpl *This = (JoystickImpl *)iface;

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(rguid), pdiph);

    if (TRACE_ON(dinput))
        _dump_DIPROPHEADER(pdiph);

    if (!HIWORD(rguid)) {
        switch ((DWORD)rguid) {
        case (DWORD) DIPROP_BUFFERSIZE: {
            LPDIPROPDWORD	pd = (LPDIPROPDWORD)pdiph;
            TRACE(" return buffersize = %d\n",This->queue_len);
            pd->dwData = This->queue_len;
            break;
        }
        case (DWORD) DIPROP_RANGE: {
            LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
            int obj = find_property(This, pdiph);
            /* The app is querying the current range of the axis
             * return the lMin and lMax values */
            if (obj >= 0) {
                pr->lMin = This->props[obj].lMin;
                pr->lMax = This->props[obj].lMax;
                TRACE("range(%ld, %ld) obj=%d\n", pr->lMin, pr->lMax, obj);
                return DI_OK;
            }
            break;
        }
        case (DWORD) DIPROP_DEADZONE: {
            LPDIPROPDWORD	pd = (LPDIPROPDWORD)pdiph;
            int obj = find_property(This, pdiph);
            if (obj >= 0) {
                pd->dwData = This->props[obj].lDeadZone;
                TRACE("deadzone(%ld) obj=%d\n", pd->dwData, obj);
                return DI_OK;
            }
            break;
        }
        case (DWORD) DIPROP_SATURATION: {
            LPDIPROPDWORD	pd = (LPDIPROPDWORD)pdiph;
            int obj = find_property(This, pdiph);
            if (obj >= 0) {
                pd->dwData = This->props[obj].lSaturation;
                TRACE("saturation(%ld) obj=%d\n", pd->dwData, obj);
                return DI_OK;
            }
            break;
        }
        default:
            FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
            break;
        }
    }

    return DI_OK;
}

/******************************************************************************
  *     GetObjectInfo : get object info
  */
HRESULT WINAPI JoystickAImpl_GetObjectInfo(
        LPDIRECTINPUTDEVICE8A iface,
        LPDIDEVICEOBJECTINSTANCEA pdidoi,
        DWORD dwObj,
        DWORD dwHow)
{
    JoystickImpl *This = (JoystickImpl *)iface;
    DIDEVICEOBJECTINSTANCEA didoiA;
    unsigned int i;

    TRACE("(%p,%p,%ld,0x%08lx(%s))\n",
          iface, pdidoi, dwObj, dwHow,
          dwHow == DIPH_BYOFFSET ? "DIPH_BYOFFSET" :
          dwHow == DIPH_BYID ? "DIPH_BYID" :
          dwHow == DIPH_BYUSAGE ? "DIPH_BYUSAGE" :
          "UNKNOWN");

    if (pdidoi == NULL) {
        WARN("invalid parameter: pdidoi = NULL\n");
        return DIERR_INVALIDPARAM;
    }

    if ((pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCEA)) &&
        (pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3A))) {
        WARN("invalid parameter: pdidoi->dwSize = %ld != %d or %d\n",
             pdidoi->dwSize, sizeof(DIDEVICEOBJECTINSTANCEA),
             sizeof(DIDEVICEOBJECTINSTANCE_DX3A));
        return DIERR_INVALIDPARAM;
    }

    ZeroMemory(&didoiA, sizeof(didoiA));
    didoiA.dwSize = pdidoi->dwSize;

    switch (dwHow) {
    case DIPH_BYOFFSET: {
        int axis = 0;
        int pov = 0;
        int button = 0;
        for (i = 0; i < This->user_df->dwNumObjs; i++) {
            if (This->user_df->rgodf[i].dwOfs == dwObj) {
                if (This->user_df->rgodf[i].pguid)
                    didoiA.guidType = *This->user_df->rgodf[i].pguid;
                else
                    didoiA.guidType = GUID_NULL;

                didoiA.dwOfs = dwObj;
                didoiA.dwType = This->user_df->rgodf[i].dwType;
                didoiA.dwFlags = This->user_df->rgodf[i].dwFlags;

                if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_AXIS)
                    sprintf(didoiA.tszName, "Axis %d", axis);
                else if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_POV)
                    sprintf(didoiA.tszName, "POV %d", pov);
                else if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_BUTTON)
                    sprintf(didoiA.tszName, "Button %d", button);

                CopyMemory(pdidoi, &didoiA, pdidoi->dwSize);
                return DI_OK;
            }

            if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_AXIS)
                axis++;
            else if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_POV)
                pov++;
            else if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_BUTTON)
                button++;
        }
        break;
    }
    case DIPH_BYID:
        FIXME("dwHow = DIPH_BYID not implemented\n");
        break;
    case DIPH_BYUSAGE:
        FIXME("dwHow = DIPH_BYUSAGE not implemented\n");
        break;
    default:
        WARN("invalid parameter: dwHow = %08lx\n", dwHow);
        return DIERR_INVALIDPARAM;
    }

    CopyMemory(pdidoi, &didoiA, pdidoi->dwSize);

    return DI_OK;
}

/******************************************************************************
  *     GetDeviceInfo : get information about a device's identity
  */
HRESULT WINAPI JoystickAImpl_GetDeviceInfo(
    LPDIRECTINPUTDEVICE8A iface,
    LPDIDEVICEINSTANCEA pdidi)
{
    JoystickImpl *This = (JoystickImpl *)iface;

    TRACE("(%p,%p)\n", iface, pdidi);

    if (pdidi == NULL) {
        WARN("invalid pointer\n");
        return E_POINTER;
    }

    if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3A)) &&
        (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA))) {
        WARN("invalid parameter: pdidi->dwSize = %ld != %d or %d\n",
             pdidi->dwSize, sizeof(DIDEVICEINSTANCE_DX3A),
             sizeof(DIDEVICEINSTANCEA));
        return DIERR_INVALIDPARAM;
    }

    /* Return joystick */
    pdidi->guidInstance = GUID_Joystick;
    pdidi->guidProduct = DInput_Wine_Joystick_GUID;
    /* we only support traditional joysticks for now */
    pdidi->dwDevType = This->devcaps.dwDevType;
    strcpy(pdidi->tszInstanceName, "Joystick");
    strcpy(pdidi->tszProductName, This->name);
    if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3A)) {
        pdidi->guidFFDriver = GUID_NULL;
        pdidi->wUsagePage = 0;
        pdidi->wUsage = 0;
    }

    return DI_OK;
}

/******************************************************************************
  *     GetDeviceInfo : get information about a device's identity
  */
HRESULT WINAPI JoystickWImpl_GetDeviceInfo(
    LPDIRECTINPUTDEVICE8W iface,
    LPDIDEVICEINSTANCEW pdidi)
{
    JoystickImpl *This = (JoystickImpl *)iface;

    TRACE("(%p,%p)\n", iface, pdidi);

    if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) &&
        (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW))) {
        WARN("invalid parameter: pdidi->dwSize = %ld != %d or %d\n",
             pdidi->dwSize, sizeof(DIDEVICEINSTANCE_DX3W),
             sizeof(DIDEVICEINSTANCEW));
        return DIERR_INVALIDPARAM;
    }

    /* Return joystick */
    pdidi->guidInstance = GUID_Joystick;
    pdidi->guidProduct = DInput_Wine_Joystick_GUID;
    /* we only support traditional joysticks for now */
    pdidi->dwDevType = This->devcaps.dwDevType;
    MultiByteToWideChar(CP_ACP, 0, "Joystick", -1, pdidi->tszInstanceName, MAX_PATH);
    MultiByteToWideChar(CP_ACP, 0, This->name, -1, pdidi->tszProductName, MAX_PATH);
    if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3W)) {
        pdidi->guidFFDriver = GUID_NULL;
        pdidi->wUsagePage = 0;
        pdidi->wUsage = 0;
    }

    return DI_OK;
}

static const IDirectInputDevice8AVtbl JoystickAvt =
{
	IDirectInputDevice2AImpl_QueryInterface,
	IDirectInputDevice2AImpl_AddRef,
	JoystickAImpl_Release,
	JoystickAImpl_GetCapabilities,
	JoystickAImpl_EnumObjects,
	JoystickAImpl_GetProperty,
	JoystickAImpl_SetProperty,
	JoystickAImpl_Acquire,
	JoystickAImpl_Unacquire,
	JoystickAImpl_GetDeviceState,
	JoystickAImpl_GetDeviceData,
	JoystickAImpl_SetDataFormat,
	JoystickAImpl_SetEventNotification,
	IDirectInputDevice2AImpl_SetCooperativeLevel,
	JoystickAImpl_GetObjectInfo,
	JoystickAImpl_GetDeviceInfo,
	IDirectInputDevice2AImpl_RunControlPanel,
	IDirectInputDevice2AImpl_Initialize,
	IDirectInputDevice2AImpl_CreateEffect,
	IDirectInputDevice2AImpl_EnumEffects,
	IDirectInputDevice2AImpl_GetEffectInfo,
	IDirectInputDevice2AImpl_GetForceFeedbackState,
	IDirectInputDevice2AImpl_SendForceFeedbackCommand,
	IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
	IDirectInputDevice2AImpl_Escape,
	JoystickAImpl_Poll,
	IDirectInputDevice2AImpl_SendDeviceData,
	IDirectInputDevice7AImpl_EnumEffectsInFile,
	IDirectInputDevice7AImpl_WriteEffectToFile,
	IDirectInputDevice8AImpl_BuildActionMap,
	IDirectInputDevice8AImpl_SetActionMap,
	IDirectInputDevice8AImpl_GetImageInfo
};

#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun)	(typeof(SysJoystickWvt.fun))
#else
# define XCAST(fun)	(void*)
#endif

static const IDirectInputDevice8WVtbl SysJoystickWvt =
{
	IDirectInputDevice2WImpl_QueryInterface,
	XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
	XCAST(Release)JoystickAImpl_Release,
	XCAST(GetCapabilities)JoystickAImpl_GetCapabilities,
	JoystickWImpl_EnumObjects,
	XCAST(GetProperty)JoystickAImpl_GetProperty,
	XCAST(SetProperty)JoystickAImpl_SetProperty,
	XCAST(Acquire)JoystickAImpl_Acquire,
	XCAST(Unacquire)JoystickAImpl_Unacquire,
	XCAST(GetDeviceState)JoystickAImpl_GetDeviceState,
	XCAST(GetDeviceData)JoystickAImpl_GetDeviceData,
	XCAST(SetDataFormat)JoystickAImpl_SetDataFormat,
	XCAST(SetEventNotification)JoystickAImpl_SetEventNotification,
	XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
	IDirectInputDevice2WImpl_GetObjectInfo,
	JoystickWImpl_GetDeviceInfo,
	XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
	XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
	XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
	IDirectInputDevice2WImpl_EnumEffects,
	IDirectInputDevice2WImpl_GetEffectInfo,
	XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState,
	XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
	XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
	XCAST(Escape)IDirectInputDevice2AImpl_Escape,
	XCAST(Poll)JoystickAImpl_Poll,
	XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
        IDirectInputDevice7WImpl_EnumEffectsInFile,
        IDirectInputDevice7WImpl_WriteEffectToFile,
        IDirectInputDevice8WImpl_BuildActionMap,
        IDirectInputDevice8WImpl_SetActionMap,
        IDirectInputDevice8WImpl_GetImageInfo
};
#undef XCAST

#else  /* HAVE_LINUX_22_JOYSTICK_API */

const struct dinput_device joystick_linux_device = {
  "Wine Linux joystick driver",
  NULL,
  NULL,
  NULL,
  NULL
};

#endif  /* HAVE_LINUX_22_JOYSTICK_API */
