[PATCH 3/6] dinput: Remove legacy joystick backends.

Rémi Bernon rbernon at codeweavers.com
Mon Oct 11 03:10:57 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 configure.ac                      |    1 -
 dlls/dinput/Makefile.in           |    6 -
 dlls/dinput/device.c              |   34 +-
 dlls/dinput/device_private.h      |   27 -
 dlls/dinput/dinput_main.c         |    3 -
 dlls/dinput/dinput_private.h      |    3 -
 dlls/dinput/effect_linuxinput.c   |  906 ---------------
 dlls/dinput/joystick.c            |  962 ----------------
 dlls/dinput/joystick_hid.c        |    8 +-
 dlls/dinput/joystick_linux.c      |  831 --------------
 dlls/dinput/joystick_linuxinput.c | 1276 ---------------------
 dlls/dinput/joystick_osx.c        | 1704 -----------------------------
 dlls/dinput/joystick_private.h    |   91 --
 dlls/dinput8/Makefile.in          |    6 -
 14 files changed, 6 insertions(+), 5852 deletions(-)
 delete mode 100644 dlls/dinput/effect_linuxinput.c
 delete mode 100644 dlls/dinput/joystick.c
 delete mode 100644 dlls/dinput/joystick_linux.c
 delete mode 100644 dlls/dinput/joystick_linuxinput.c
 delete mode 100644 dlls/dinput/joystick_osx.c
 delete mode 100644 dlls/dinput/joystick_private.h

diff --git a/configure.ac b/configure.ac
index 530785c0033..a157c948fec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -740,7 +740,6 @@ case $host_os in
     dnl declare needed frameworks
     AC_SUBST(COREFOUNDATION_LIBS,"-framework CoreFoundation")
     AC_SUBST(IOKIT_LIBS,"-framework IOKit -framework CoreFoundation")
-    AC_SUBST(FORCEFEEDBACK_LIBS,"-framework ForceFeedback -framework CoreFoundation")
     AC_SUBST(APPLICATIONSERVICES_LIBS,"-framework ApplicationServices")
     AC_SUBST(CORESERVICES_LIBS,"-framework CoreServices")
     AC_SUBST(APPKIT_LIBS,"-framework AppKit")
diff --git a/dlls/dinput/Makefile.in b/dlls/dinput/Makefile.in
index 0db023ee7fe..7bd5951a7a1 100644
--- a/dlls/dinput/Makefile.in
+++ b/dlls/dinput/Makefile.in
@@ -2,7 +2,6 @@ MODULE    = dinput.dll
 IMPORTLIB = dinput
 IMPORTS   = dinput dxguid uuid comctl32 ole32 user32 advapi32 hid setupapi
 EXTRADEFS = -DDIRECTINPUT_VERSION=0x0700
-EXTRALIBS = $(IOKIT_LIBS) $(FORCEFEEDBACK_LIBS)
 
 EXTRADLLFLAGS = -mcygwin
 
@@ -12,12 +11,7 @@ C_SRCS = \
 	data_formats.c \
 	device.c \
 	dinput_main.c \
-	effect_linuxinput.c \
-	joystick.c \
 	joystick_hid.c \
-	joystick_linux.c \
-	joystick_linuxinput.c \
-	joystick_osx.c \
 	keyboard.c \
 	mouse.c
 
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 484fe904c2e..65698ad64f5 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -187,11 +187,6 @@ void _dump_DIPROPHEADER(LPCDIPROPHEADER diph) {
     }
 }
 
-void _dump_OBJECTINSTANCEA(const DIDEVICEOBJECTINSTANCEA *ddoi) {
-    TRACE("    - enumerating : %s ('%s') - %2d - 0x%08x - %s - 0x%x\n",
-        debugstr_guid(&ddoi->guidType), _dump_dinput_GUID(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, ddoi->tszName, ddoi->dwFlags);
-}
-
 void _dump_OBJECTINSTANCEW(const DIDEVICEOBJECTINSTANCEW *ddoi) {
     TRACE("    - enumerating : %s ('%s'), - %2d - 0x%08x - %s - 0x%x\n",
         debugstr_guid(&ddoi->guidType), _dump_dinput_GUID(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, debugstr_w(ddoi->tszName), ddoi->dwFlags);
@@ -437,7 +432,7 @@ void fill_DataFormat(void *out, DWORD size, const void *in, const DataFormat *df
     }
 }
 
-void release_DataFormat(DataFormat * format)
+static void release_DataFormat( DataFormat *format )
 {
     TRACE("Deleting DataFormat: %p\n", format);
 
@@ -637,20 +632,7 @@ static int verify_offset(const DataFormat *df, int offset)
     return -1;
 }
 
-/* find an object by its offset in a data format */
-static int offset_to_object(const DataFormat *df, int offset)
-{
-    int i;
-
-    if (!df->offsets) return -1;
-
-    for (i = 0; i < df->wine_df->dwNumObjs; i++)
-        if (df->offsets[i] == offset) return i;
-
-    return -1;
-}
-
-int id_to_object(LPCDIDATAFORMAT df, int id)
+static int id_to_object( LPCDIDATAFORMAT df, int id )
 {
     int i;
 
@@ -669,18 +651,6 @@ static int id_to_offset(const DataFormat *df, int id)
     return obj >= 0 && df->offsets ? df->offsets[obj] : -1;
 }
 
-int find_property(const DataFormat *df, LPCDIPROPHEADER ph)
-{
-    switch (ph->dwHow)
-    {
-        case DIPH_BYID:     return id_to_object(df->wine_df, ph->dwObj);
-        case DIPH_BYOFFSET: return offset_to_object(df, ph->dwObj);
-    }
-    FIXME("Unhandled ph->dwHow=='%04X'\n", (unsigned int)ph->dwHow);
-
-    return -1;
-}
-
 static DWORD semantic_to_obj_id(IDirectInputDeviceImpl* This, DWORD dwSemantic)
 {
     DWORD type = (0x0000ff00 & dwSemantic) >> 8;
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index 2b939fd5a0c..321a9702642 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -102,43 +102,16 @@ extern BOOL device_instance_is_disabled( DIDEVICEINSTANCEW *instance, BOOL *over
 
 /* Routines to do DataFormat / WineFormat conversions */
 extern void fill_DataFormat(void *out, DWORD size, const void *in, const DataFormat *df)  DECLSPEC_HIDDEN;
-extern void release_DataFormat(DataFormat *df)  DECLSPEC_HIDDEN;
 extern void queue_event( IDirectInputDevice8W *iface, int inst_id, DWORD data, DWORD time, DWORD seq ) DECLSPEC_HIDDEN;
-/* Helper functions to work with data format */
-extern int id_to_object(LPCDIDATAFORMAT df, int id) DECLSPEC_HIDDEN;
-extern int find_property(const DataFormat *df, LPCDIPROPHEADER ph) DECLSPEC_HIDDEN;
-
-/* Common joystick stuff */
-typedef struct
-{
-    LONG lDevMin;
-    LONG lDevMax;
-    LONG lMin;
-    LONG lMax;
-    LONG lDeadZone;
-    LONG lSaturation;
-} ObjProps;
-
-extern DWORD joystick_map_pov(const POINTL *p) DECLSPEC_HIDDEN;
-extern LONG joystick_map_axis(ObjProps *props, int val) DECLSPEC_HIDDEN;
-
-typedef struct
-{
-    struct list entry;
-    LPDIRECTINPUTEFFECT ref;
-} effect_list_item;
 
 extern const GUID dinput_pidvid_guid DECLSPEC_HIDDEN;
 
 /* Various debug tools */
 extern void _dump_DIPROPHEADER(LPCDIPROPHEADER diph)  DECLSPEC_HIDDEN;
-extern void _dump_OBJECTINSTANCEA(const DIDEVICEOBJECTINSTANCEA *ddoi)  DECLSPEC_HIDDEN;
 extern void _dump_OBJECTINSTANCEW(const DIDEVICEOBJECTINSTANCEW *ddoi)  DECLSPEC_HIDDEN;
 extern void _dump_DIDATAFORMAT(const DIDATAFORMAT *df)  DECLSPEC_HIDDEN;
 extern const char *_dump_dinput_GUID(const GUID *guid)  DECLSPEC_HIDDEN;
 
-extern LPDIOBJECTDATAFORMAT dataformat_to_odf_by_type(LPCDIDATAFORMAT df, int n, DWORD type)   DECLSPEC_HIDDEN;
-
 extern HRESULT _build_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags, DWORD devMask, LPCDIDATAFORMAT df)  DECLSPEC_HIDDEN;
 extern HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags, LPCDIDATAFORMAT df) DECLSPEC_HIDDEN;
 
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 9c0e3875c00..88f338a426d 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -78,9 +78,6 @@ static const struct dinput_device *dinput_devices[] =
 {
     &mouse_device,
     &keyboard_device,
-    &joystick_linuxinput_device,
-    &joystick_linux_device,
-    &joystick_osx_device,
     &joystick_hid_device,
 };
 
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index c11b64585d9..949e84957d0 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -68,9 +68,6 @@ struct DevicePlayer {
 extern const struct dinput_device mouse_device DECLSPEC_HIDDEN;
 extern const struct dinput_device keyboard_device DECLSPEC_HIDDEN;
 extern const struct dinput_device joystick_hid_device DECLSPEC_HIDDEN;
-extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN;
-extern const struct dinput_device joystick_linuxinput_device DECLSPEC_HIDDEN;
-extern const struct dinput_device joystick_osx_device DECLSPEC_HIDDEN;
 
 extern void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface);
 extern void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface);
diff --git a/dlls/dinput/effect_linuxinput.c b/dlls/dinput/effect_linuxinput.c
deleted file mode 100644
index 486163aeffa..00000000000
--- a/dlls/dinput/effect_linuxinput.c
+++ /dev/null
@@ -1,906 +0,0 @@
-/*              DirectInput Linux Event Device Effect
- *
- * Copyright 2005 Daniel Remenak
- *
- * Thanks to Google's Summer of Code Program (2005)
- *
- * 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"
-
-#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
-
-#include <stdarg.h>
-#include <string.h>
-#ifdef HAVE_LINUX_INPUT_H
-#  include <linux/input.h>
-#  undef SW_MAX
-#endif
-#include <limits.h>
-#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-#endif
-#include <math.h>
-#include "wine/debug.h"
-#include "wine/unicode.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "dinput.h"
-
-#include "device_private.h"
-#include "joystick_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(dinput);
-
-static const IDirectInputEffectVtbl LinuxInputEffectVtbl;
-typedef struct LinuxInputEffectImpl LinuxInputEffectImpl;
-struct LinuxInputEffectImpl
-{
-    IDirectInputEffect  IDirectInputEffect_iface;
-    LONG                ref;
-    GUID                guid;
-
-    struct ff_effect    effect; /* Effect data */
-    int                 gain;   /* Effect gain */
-    BOOL                first_axis_is_x;
-    int*                fd;     /* Parent device */
-    struct list        *entry;  /* Entry into the parent's list of effects */
-};
-
-static inline LinuxInputEffectImpl *impl_from_IDirectInputEffect(IDirectInputEffect *iface)
-{
-    return CONTAINING_RECORD(iface, LinuxInputEffectImpl, IDirectInputEffect_iface);
-}
-
-static double ff_effect_direction_to_rad(unsigned int dir)
-{
-    return (dir & 0xffff) * M_PI / 0x8000;
-}
-
-static void ff_dump_effect(struct ff_effect *effect)
-{
-    const char *type = "(Unknown)", *length = "INFINITE";
-    struct ff_envelope *env = NULL;
-    double angle;
-#define FE(x) case x: type = #x; break
-    switch (effect->type)
-    {
-        FE(FF_RUMBLE);
-        FE(FF_PERIODIC);
-        FE(FF_CONSTANT);
-        FE(FF_SPRING);
-        FE(FF_FRICTION);
-        FE(FF_DAMPER);
-        FE(FF_INERTIA);
-        FE(FF_RAMP);
-    }
-#undef FE
-
-    /* rotate so 0 points right */
-    angle = 360 - ff_effect_direction_to_rad(effect->direction + 0xc000) * 180 / M_PI;
-
-    if (effect->replay.length)
-      length = wine_dbg_sprintf("%u ms", effect->replay.length);
-
-    TRACE("type 0x%x %s, id %d, direction 0x%x (source angle %.2f), time length %s, start delay %u ms\n",
-          effect->type, type, effect->id, effect->direction, angle, length, effect->replay.delay);
-    if (effect->trigger.button || effect->trigger.interval)
-        TRACE(" -> trigger button %u, re-trigger interval %u ms\n",
-              effect->trigger.button, effect->trigger.interval);
-
-    if (effect->type == FF_PERIODIC)
-    {
-        struct ff_periodic_effect *per = &effect->u.periodic;
-        const char *wave = "(Unknown)";
-#define FE(x) case x: wave = #x; break
-        switch (per->waveform)
-        {
-            FE(FF_SQUARE);
-            FE(FF_TRIANGLE);
-            FE(FF_SINE);
-            FE(FF_SAW_UP);
-            FE(FF_SAW_DOWN);
-            FE(FF_CUSTOM);
-        }
-#undef FE
-        angle = ff_effect_direction_to_rad(per->phase) * 180 / M_PI;
-        TRACE(" -> waveform 0x%x %s, period %u ms, magnitude %d, offset %d, phase 0x%x (angle %.2f), custom len %d\n",
-              per->waveform, wave, per->period, per->magnitude, per->offset, per->phase, angle, per->custom_len);
-        env = &per->envelope;
-    }
-    else if (effect->type == FF_CONSTANT)
-    {
-        struct ff_constant_effect *cons = &effect->u.constant;
-        TRACE(" -> level %d\n", cons->level);
-        env = &cons->envelope;
-    }
-    else if (effect->type == FF_RAMP)
-    {
-        struct ff_ramp_effect *ramp = &effect->u.ramp;
-        TRACE(" -> start/end level %d/%d\n", ramp->start_level, ramp->end_level);
-        env = &ramp->envelope;
-    }
-    else if (effect->type == FF_RUMBLE)
-    {
-        struct ff_rumble_effect *rumble = &effect->u.rumble;
-        TRACE(" -> strong/weak magnitude %u/%u\n", rumble->strong_magnitude, rumble->weak_magnitude);
-    }
-    else if (effect->type == FF_SPRING || effect->type == FF_FRICTION ||
-             effect->type == FF_DAMPER || effect->type == FF_INERTIA)
-    {
-        struct ff_condition_effect *cond = effect->u.condition;
-        int i;
-        for (i = 0; i < 2; i++)
-        {
-            /* format numbers here to make them align correctly */
-            TRACE(" -> [%d] right/left saturation %5u/%5u, right/left coefficient %5d/%5d,"
-                  " deadband %5u, center %5d\n", i, cond[i].right_saturation, cond[i].left_saturation,
-                  cond[i].right_coeff, cond[i].left_coeff, cond[i].deadband, cond[i].center);
-        }
-    }
-
-    if (env)
-        TRACE(" -> envelope attack length(ms)/level %u/%u, fade length(ms)/level %u/%u\n",
-              env->attack_length, env->attack_level, env->fade_length, env->fade_level);
-}
-
-/******************************************************************************
- *      LinuxInputEffectImpl 
- */
-
-static ULONG WINAPI LinuxInputEffectImpl_AddRef(
-	LPDIRECTINPUTEFFECT iface)
-{
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-    ULONG ref = InterlockedIncrement(&This->ref);
-    TRACE( "(%p) ref %d\n", This, ref );
-    return ref;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_Download(
-	LPDIRECTINPUTEFFECT iface)
-{
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-    int ret, old_effect_id;
-
-    TRACE("(this=%p)\n", This);
-    ff_dump_effect(&This->effect);
-
-    old_effect_id = This->effect.id;
-    if (ioctl(*(This->fd), EVIOCSFF, &This->effect) != -1)
-        return DI_OK;
-
-    /* Linux kernel < 3.14 has a bug that incorrectly assigns an effect ID even
-     * on error, restore it here if that is the case. */
-    This->effect.id = old_effect_id;
-
-    switch (errno)
-    {
-        case EINVAL:
-            ret = DIERR_INVALIDPARAM;
-            break;
-        case ENOSPC:
-            ret = DIERR_DEVICEFULL;
-            break;
-        case ENOMEM:
-            ret = DIERR_OUTOFMEMORY;
-            break;
-        default:
-            ret = DIERR_INPUTLOST;
-            break;
-    }
-    TRACE("Could not upload effect to fd %d, errno %d \"%s\", returning 0x%x.\n",
-          *This->fd, errno, strerror(errno), ret);
-    return ret;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_Escape(
-	LPDIRECTINPUTEFFECT iface,
-        LPDIEFFESCAPE pesc)
-{
-    WARN("(this=%p,%p): invalid: no hardware-specific escape codes in this" 
-         " driver!\n", iface, pesc);
-
-    return DI_OK;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_GetEffectGuid(
-        LPDIRECTINPUTEFFECT iface,
-	LPGUID pguid)
-{
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-
-    TRACE("(this=%p,%p)\n", This, pguid);
-
-    *pguid = This->guid;
-
-    return DI_OK;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_GetEffectStatus(
-        LPDIRECTINPUTEFFECT iface,
-	LPDWORD pdwFlags)
-{
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-
-    TRACE("(this=%p,%p)\n", This, pdwFlags);
-
-    if (!pdwFlags)
-        return E_POINTER;
-
-    if (This->effect.id == -1)
-        return DIERR_NOTDOWNLOADED;
-
-    /* linux sends the effect status through an event.
-     * that event is trapped by our parent joystick driver
-     * and there is no clean way to pass it back to us. */
-    FIXME("Not enough information to provide a status.\n");
-
-    (*pdwFlags) = 0;
-
-    return DI_OK;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_GetParameters(
-	LPDIRECTINPUTEFFECT iface,
-	LPDIEFFECT peff,
-	DWORD dwFlags)
-{
-    HRESULT diErr = DI_OK;
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("(this=%p,%p,%d)\n", This, peff, dwFlags);
-
-    /* Major conversion factors are:
-     * times: millisecond (linux) -> microsecond (windows) (x * 1000)
-     * forces: scale 0x7FFF (linux) -> scale 10000 (windows) approx ((x / 33) * 10)
-     * angles: scale 0x7FFF (linux) -> scale 35999 (windows) approx ((x / 33) * 36)
-     * angle bases: 0 -> -y (down) (linux) -> 0 -> +x (right) (windows)
-     */
-
-    if (dwFlags & DIEP_AXES) {
-	if (peff->cAxes < 2 /* linuxinput effects always use 2 axes, x and y */)
-	    diErr = DIERR_MOREDATA;
-	peff->cAxes = 2; 
-	if (diErr)
-	    return diErr;
-	else {
-	    peff->rgdwAxes[0] = DIJOFS_X;
-	    peff->rgdwAxes[1] = DIJOFS_Y;
-	}
-    }
- 
-    if (dwFlags & DIEP_DIRECTION) {
-        if (peff->cAxes < 2)
-            diErr = DIERR_MOREDATA;
-        peff->cAxes = 2; 
-        if (diErr)
-            return diErr;
-        else {
-	    if (peff->dwFlags & DIEFF_CARTESIAN) {
-		/* rotate so 0 points right */
-		double angle = ff_effect_direction_to_rad(This->effect.direction + 0xc000);
-		peff->rglDirection[0] = sin(angle) * 1000;
-		peff->rglDirection[1] = -cos(angle) * 1000;
-	    } else {
-		/* Polar and spherical coordinates are the same for two or less
-		 * axes.
-		 * Note that we also use this case if NO flags are marked.
-		 * According to MSDN, we should return the direction in the
-		 * format that it was specified in, if no flags are marked.
-		 */
-		peff->rglDirection[0] = (This->effect.direction / 33) * 36 + 9000;
-		if (peff->rglDirection[0] > 35999)
-		    peff->rglDirection[0] -= 35999;
-	    }
-	}
-    }
-
-    if (dwFlags & DIEP_DURATION)
-    {
-        if (!This->effect.replay.length) /* infinite for the linux driver */
-            peff->dwDuration = INFINITE;
-        else
-            peff->dwDuration = (DWORD)This->effect.replay.length * 1000;
-    }
-
-    if (dwFlags & DIEP_ENVELOPE) {
-	struct ff_envelope* env;
-	if (This->effect.type == FF_CONSTANT) env = &This->effect.u.constant.envelope;
-	else if (This->effect.type == FF_PERIODIC) env = &This->effect.u.periodic.envelope;
-	else if (This->effect.type == FF_RAMP) env = &This->effect.u.ramp.envelope;
-	else env = NULL;
-	if (env == NULL) {
-	    peff->lpEnvelope = NULL;
-	} else if (peff->lpEnvelope == NULL) {
-	    return DIERR_INVALIDPARAM;
-	} else { 
-	    peff->lpEnvelope->dwAttackLevel = (env->attack_level / 33) * 10;
-	    peff->lpEnvelope->dwAttackTime = env->attack_length * 1000;
-	    peff->lpEnvelope->dwFadeLevel = (env->fade_level / 33) * 10;
-	    peff->lpEnvelope->dwFadeTime = env->fade_length * 1000;
-	}
-    }
-
-    if (dwFlags & DIEP_GAIN) {
-	peff->dwGain = This->gain * 10000 / 0xFFFF;
-    }
-
-    if (dwFlags & DIEP_SAMPLEPERIOD) {
-	/* the linux input ff driver has no support for setting
-	 * the playback sample period.  0 means default. */
-    	peff->dwSamplePeriod = 0;
-    }
-
-    if ((dwFlags & DIEP_STARTDELAY) && peff->dwSize > sizeof(DIEFFECT_DX5))
-        peff->dwStartDelay = This->effect.replay.delay * 1000;
-
-    if (dwFlags & DIEP_TRIGGERBUTTON) {
-	FIXME("LinuxInput button mapping needs redoing; for now, assuming we're using an actual joystick.\n");
-	peff->dwTriggerButton = DIJOFS_BUTTON(This->effect.trigger.button - BTN_JOYSTICK);
-    }
-
-    if (dwFlags & DIEP_TRIGGERREPEATINTERVAL) {
-	peff->dwTriggerRepeatInterval = This->effect.trigger.interval * 1000;
-    }
-
-    if (dwFlags & DIEP_TYPESPECIFICPARAMS) {
-	DWORD expectedsize = 0;
-	if (This->effect.type == FF_PERIODIC) {
-	    expectedsize = sizeof(DIPERIODIC);
-	} else if (This->effect.type == FF_CONSTANT) {
-	    expectedsize = sizeof(DICONSTANTFORCE);
-	} else if (This->effect.type == FF_SPRING 
-		|| This->effect.type == FF_FRICTION 
-		|| This->effect.type == FF_INERTIA 
-		|| This->effect.type == FF_DAMPER) {
-	    expectedsize = sizeof(DICONDITION) * 2;
-	} else if (This->effect.type == FF_RAMP) {
-	    expectedsize = sizeof(DIRAMPFORCE);
-	}
-	if (expectedsize > peff->cbTypeSpecificParams)
-	    diErr = DIERR_MOREDATA;
-	peff->cbTypeSpecificParams = expectedsize;
-	if (diErr)
-	    return diErr;
-	else {
-	    if (This->effect.type == FF_PERIODIC) {
-                LPDIPERIODIC tsp = peff->lpvTypeSpecificParams;
-		tsp->dwMagnitude = (This->effect.u.periodic.magnitude / 33) * 10;
-		tsp->lOffset = (This->effect.u.periodic.offset / 33) * 10;
-		tsp->dwPhase = (This->effect.u.periodic.phase / 33) * 36;
-		tsp->dwPeriod = (This->effect.u.periodic.period * 1000);
-	    } else if (This->effect.type == FF_CONSTANT) {
-                LPDICONSTANTFORCE tsp = peff->lpvTypeSpecificParams;
-		tsp->lMagnitude = (This->effect.u.constant.level / 33) * 10;
-	    } else if (This->effect.type == FF_SPRING 
-		    || This->effect.type == FF_FRICTION 
-		    || This->effect.type == FF_INERTIA 
-		    || This->effect.type == FF_DAMPER) {
-                LPDICONDITION tsp = peff->lpvTypeSpecificParams;
-		int i;
-		for (i = 0; i < 2; ++i) {
-		    tsp[i].lOffset = (This->effect.u.condition[i].center / 33) * 10; 
-		    tsp[i].lPositiveCoefficient = (This->effect.u.condition[i].right_coeff / 33) * 10;
-		    tsp[i].lNegativeCoefficient = (This->effect.u.condition[i].left_coeff / 33) * 10; 
-		    tsp[i].dwPositiveSaturation = (This->effect.u.condition[i].right_saturation / 33) * 10;
-		    tsp[i].dwNegativeSaturation = (This->effect.u.condition[i].left_saturation / 33) * 10;
-		    tsp[i].lDeadBand = (This->effect.u.condition[i].deadband / 33) * 10;
-		}
-	    } else if (This->effect.type == FF_RAMP) {
-                LPDIRAMPFORCE tsp = peff->lpvTypeSpecificParams;
-		tsp->lStart = (This->effect.u.ramp.start_level / 33) * 10;
-		tsp->lEnd = (This->effect.u.ramp.end_level / 33) * 10;
-	    }
-	}
-    } 
-
-    return diErr;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_Initialize(
-        LPDIRECTINPUTEFFECT iface,
-	HINSTANCE hinst,
-	DWORD dwVersion,
-	REFGUID rguid)
-{
-    FIXME("(this=%p,%p,%d,%s): stub!\n",
-	 iface, hinst, dwVersion, debugstr_guid(rguid));
-
-    return DI_OK;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_QueryInterface(
-	LPDIRECTINPUTEFFECT iface,
-	REFIID riid,
-	void **ppvObject)
-{
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-
-    TRACE("(this=%p,%s,%p)\n", This, debugstr_guid(riid), ppvObject);
-
-    if (IsEqualGUID(&IID_IUnknown, riid) ||
-	IsEqualGUID(&IID_IDirectInputEffect, riid)) {
-	    LinuxInputEffectImpl_AddRef(iface);
-	    *ppvObject = This;
-	    return 0;
-    }
-
-    TRACE("Unsupported interface!\n");
-    return E_FAIL;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_Start(
-	LPDIRECTINPUTEFFECT iface,
-	DWORD dwIterations,
-	DWORD dwFlags)
-{
-    struct input_event event;
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-
-    TRACE("(this=%p,%d,%d)\n", This, dwIterations, dwFlags);
-
-    if (!(dwFlags & DIES_NODOWNLOAD)) {
-	/* Download the effect if necessary */
-	if (This->effect.id == -1) {
-	    HRESULT res = LinuxInputEffectImpl_Download(iface);
-	    if (res != DI_OK)
-		return res;
-	}
-    }
-
-    if (dwFlags & DIES_SOLO) {
-	FIXME("Solo mode requested: should be stopping all effects here!\n");
-    }
-
-    event.type = EV_FF;
-    event.code = This->effect.id;
-    event.value = min( dwIterations, INT_MAX );
-    if (write(*(This->fd), &event, sizeof(event)) == -1) {
-	FIXME("Unable to write event.  Assuming device disconnected.\n");
-	return DIERR_INPUTLOST;
-    }
-
-    return DI_OK;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
-        LPDIRECTINPUTEFFECT iface,
-        LPCDIEFFECT peff,
-        DWORD dwFlags)
-{
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-    DWORD type = typeFromGUID(&This->guid);
-    HRESULT retval = DI_OK;
-
-    TRACE("(this=%p,%p,%d)\n", This, peff, dwFlags);
-
-    dump_DIEFFECT(peff, &This->guid, dwFlags);
-
-    if (!dwFlags)
-        return DI_NOEFFECT;
-
-    if (dwFlags & DIEP_AXES) {
-	if (!(peff->rgdwAxes))
-	    return DIERR_INVALIDPARAM;
-
-	/* the linux input effect system only supports one or two axes */
-	if (peff->cAxes > 2)
-	    return DIERR_INVALIDPARAM;
-	else if (peff->cAxes < 1)
-	    return DIERR_INCOMPLETEEFFECT;
-	This->first_axis_is_x = peff->rgdwAxes[0] == DIJOFS_X;
-    }
-
-    /* some of this may look funky, but it's 'cause the linux driver and directx have
-     * different opinions about which way direction "0" is.  directx has 0 along the x
-     * axis (left), linux has it along the y axis (down). */ 
-    if (dwFlags & DIEP_DIRECTION) {
-	if (!(peff->rglDirection))
-	    return DIERR_INVALIDPARAM;
-
-	if (peff->cAxes == 1) {
-	    if (peff->dwFlags & DIEFF_CARTESIAN) {
-		if (dwFlags & DIEP_AXES) {
-		    if (peff->rgdwAxes[0] == DIJOFS_X && peff->rglDirection[0] >= 0)
-			This->effect.direction = 0x4000;
-		    else if (peff->rgdwAxes[0] == DIJOFS_X && peff->rglDirection[0] < 0)
-			This->effect.direction = 0xC000;
-		    else if (peff->rgdwAxes[0] == DIJOFS_Y && peff->rglDirection[0] >= 0)
-			This->effect.direction = 0;
-		    else if (peff->rgdwAxes[0] == DIJOFS_Y && peff->rglDirection[0] < 0)
-			This->effect.direction = 0x8000;
-		}
-	    } else {
-		/* one-axis effects must use cartesian coords */
-		return DIERR_INVALIDPARAM;
-	    }
-        }
-        /* two axes */
-        else
-        {
-            if (peff->dwFlags & DIEFF_CARTESIAN)
-            {
-                LONG x, y;
-                if (This->first_axis_is_x)
-                {
-                    x = peff->rglDirection[0];
-                    y = peff->rglDirection[1];
-                }
-                else
-                {
-                    x = peff->rglDirection[1];
-                    y = peff->rglDirection[0];
-                }
-                This->effect.direction = (unsigned int)((M_PI / 2 + atan2(y, x)) * 0x8000 / M_PI);
-            }
-            else
-            {
-                /* Polar and spherical are the same for 2 axes */
-                /* Precision is important here, so we do double math with exact constants */
-                This->effect.direction = (unsigned int)(((double)peff->rglDirection[0] / 18000) * 0x8000);
-            }
-        }
-    }
-
-    if (dwFlags & DIEP_DURATION)
-    {
-        if (peff->dwDuration == INFINITE)
-            This->effect.replay.length = 0; /* infinite for the linux driver */
-        else if(peff->dwDuration > 1000)
-            This->effect.replay.length = peff->dwDuration / 1000;
-        else
-            This->effect.replay.length = 1;
-    }
-
-    if (dwFlags & DIEP_ENVELOPE)
-    {
-        struct ff_envelope* env;
-        if (This->effect.type == FF_CONSTANT)
-            env = &This->effect.u.constant.envelope;
-        else if (This->effect.type == FF_PERIODIC)
-            env = &This->effect.u.periodic.envelope;
-        else if (This->effect.type == FF_RAMP)
-            env = &This->effect.u.ramp.envelope;
-        else
-            env = NULL;
-
-        /* copy the envelope if it is present and the linux effect supports it */
-        if (peff->lpEnvelope && env)
-        {
-            env->attack_length = peff->lpEnvelope->dwAttackTime / 1000;
-            env->attack_level = (peff->lpEnvelope->dwAttackLevel / 10) * 32;
-            env->fade_length = peff->lpEnvelope->dwFadeTime / 1000;
-            env->fade_level = (peff->lpEnvelope->dwFadeLevel / 10) * 32;
-        }
-        /* if the dinput envelope is NULL we will clear the linux envelope */
-        else if (env)
-        {
-            env->attack_length = 0;
-            env->attack_level = 0;
-            env->fade_length = 0;
-            env->fade_level = 0;
-        }
-        else if(peff->lpEnvelope)
-        {
-            if(peff->lpEnvelope->dwAttackTime || peff->lpEnvelope->dwAttackLevel ||
-               peff->lpEnvelope->dwFadeTime || peff->lpEnvelope->dwFadeLevel)
-                WARN("Ignoring dinput envelope not supported in the linux effect\n");
-        }
-    }
-
-    /* Gain and Sample Period settings are not supported by the linux
-     * event system */
-    if (dwFlags & DIEP_GAIN) {
-	This->gain = 0xFFFF * peff->dwGain / 10000;
-	TRACE("Effect gain requested but no effect gain functionality present.\n");
-    }
-
-    if (dwFlags & DIEP_SAMPLEPERIOD)
-	TRACE("Sample period requested but no sample period functionality present.\n");
-
-    if (dwFlags & DIEP_STARTDELAY)
-    if ((dwFlags & DIEP_STARTDELAY) && peff->dwSize > sizeof(DIEFFECT_DX5))
-        This->effect.replay.delay = peff->dwStartDelay / 1000;
-
-    if (dwFlags & DIEP_TRIGGERBUTTON) {
-	if (peff->dwTriggerButton != -1) {
-	    FIXME("Linuxinput button mapping needs redoing, assuming we're using a joystick.\n");
-	    FIXME("Trigger button translation not yet implemented!\n");
-	}
-	This->effect.trigger.button = 0;
-    }
-
-    if (dwFlags & DIEP_TRIGGERREPEATINTERVAL)
-	This->effect.trigger.interval = peff->dwTriggerRepeatInterval / 1000;
-
-    if (dwFlags & DIEP_TYPESPECIFICPARAMS)
-    {
-        if (!(peff->lpvTypeSpecificParams))
-            return DIERR_INVALIDPARAM;
-
-        if (type == DIEFT_PERIODIC)
-        {
-            DIPERIODIC *tsp;
-            if (peff->cbTypeSpecificParams != sizeof(DIPERIODIC))
-                return DIERR_INVALIDPARAM;
-            tsp = peff->lpvTypeSpecificParams;
-
-            This->effect.u.periodic.magnitude = (tsp->dwMagnitude / 10) * 32;
-            This->effect.u.periodic.offset = (tsp->lOffset / 10) * 32;
-            /* phase ranges from 0 - 35999 in dinput and 0 - 65535 on Linux */
-            This->effect.u.periodic.phase = (tsp->dwPhase / 36) * 65;
-            /* dinput uses microseconds, Linux uses milliseconds */
-            if (tsp->dwPeriod <= 1000)
-                This->effect.u.periodic.period = 1;
-            else
-                This->effect.u.periodic.period = tsp->dwPeriod / 1000;
-        }
-        else if (type == DIEFT_CONSTANTFORCE)
-        {
-            LPCDICONSTANTFORCE tsp;
-            if (peff->cbTypeSpecificParams != sizeof(DICONSTANTFORCE))
-                return DIERR_INVALIDPARAM;
-            tsp = peff->lpvTypeSpecificParams;
-	    This->effect.u.constant.level = (max(min(tsp->lMagnitude, 10000), -10000) / 10) * 32;
-	} else if (type == DIEFT_RAMPFORCE) {
-            LPCDIRAMPFORCE tsp;
-            if (peff->cbTypeSpecificParams != sizeof(DIRAMPFORCE))
-                return DIERR_INVALIDPARAM;
-            tsp = peff->lpvTypeSpecificParams;
-	    This->effect.u.ramp.start_level = (tsp->lStart / 10) * 32;
-	    This->effect.u.ramp.end_level = (tsp->lEnd / 10) * 32;
-        }
-        else if (type == DIEFT_CONDITION)
-        {
-            DICONDITION *tsp = peff->lpvTypeSpecificParams;
-            struct ff_condition_effect *cond = This->effect.u.condition;
-            int i, j, sources;
-            double factor[2];
-
-            if (peff->cbTypeSpecificParams == sizeof(DICONDITION))
-            {
-                /* One condition block.  This needs to be rotated to direction,
-                 * and expanded to separate x and y conditions. Ensures 0 points right */
-                double angle = ff_effect_direction_to_rad(This->effect.direction + 0xc000);
-                factor[0] = sin(angle);
-                factor[1] = -cos(angle);
-                sources = 1;
-            }
-            else if (peff->cbTypeSpecificParams == 2 * sizeof(DICONDITION))
-            {
-                /* Direct parameter copy without changes */
-                factor[0] = factor[1] = 1;
-                sources = 2;
-            }
-            else
-                return DIERR_INVALIDPARAM;
-
-            for (i = j = 0; i < 2; ++i)
-            {
-                cond[i].center = (int)(factor[i] * (tsp[j].lOffset / 10) * 32);
-                cond[i].right_coeff = (int)(factor[i] * (tsp[j].lPositiveCoefficient / 10) * 32);
-                cond[i].left_coeff = (int)(factor[i] * (tsp[j].lNegativeCoefficient / 10) * 32);
-                cond[i].right_saturation = (int)(factor[i] * (tsp[j].dwPositiveSaturation / 10) * 65);
-                cond[i].left_saturation = (int)(factor[i] * (tsp[j].dwNegativeSaturation / 10) * 65);
-                cond[i].deadband = (int)(factor[i] * (tsp[j].lDeadBand / 10) * 32);
-                if (sources == 2)
-                    j++;
-            }
-        }
-        else
-        {
-            FIXME("Custom force types are not supported\n");
-            return DIERR_INVALIDPARAM;
-        }
-    }
-
-    if (!(dwFlags & DIEP_NODOWNLOAD))
-	retval = LinuxInputEffectImpl_Download(iface);
-    if (retval != DI_OK)
-	return DI_DOWNLOADSKIPPED;
-
-    if (dwFlags & DIEP_NORESTART)
-	TRACE("DIEP_NORESTART: not handled (we have no control of that).\n");
-
-    if (dwFlags & DIEP_START)
-	retval = LinuxInputEffectImpl_Start(iface, 1, 0);
-    if (retval != DI_OK)
-	return retval;
- 
-    return DI_OK;
-}   
-
-static HRESULT WINAPI LinuxInputEffectImpl_Stop(
-        LPDIRECTINPUTEFFECT iface)
-{
-    struct input_event event;
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-
-    TRACE("(this=%p)\n", This);
-
-    event.type = EV_FF;
-    event.code = This->effect.id;
-    event.value = 0;
-    /* we don't care about the success or failure of this call */
-    write(*(This->fd), &event, sizeof(event));
-
-    return DI_OK;
-}
-
-static HRESULT WINAPI LinuxInputEffectImpl_Unload(
-	LPDIRECTINPUTEFFECT iface)
-{
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("(this=%p)\n", This);
-
-    /* Erase the downloaded effect */
-    if (ioctl(*(This->fd), EVIOCRMFF, This->effect.id) == -1)
-	return DIERR_INVALIDPARAM;
-
-    /* Mark the effect as deallocated */
-    This->effect.id = -1;
-
-    return DI_OK;
-}
-
-static ULONG WINAPI LinuxInputEffectImpl_Release(LPDIRECTINPUTEFFECT iface)
-{
-    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
-    ULONG ref = InterlockedDecrement(&(This->ref));
-
-    TRACE( "(%p) ref %d\n", This, ref );
-
-    if (ref == 0)
-    {
-        LinuxInputEffectImpl_Stop(iface);
-        LinuxInputEffectImpl_Unload(iface);
-        list_remove(This->entry);
-        HeapFree(GetProcessHeap(), 0, LIST_ENTRY(This->entry, effect_list_item, entry));
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-    return ref;
-}
-
-/******************************************************************************
- *      LinuxInputEffect
- */
-
-DECLSPEC_HIDDEN HRESULT linuxinput_create_effect(
-	int* fd,
-	REFGUID rguid,
-        struct list *parent_list_entry,
-	LPDIRECTINPUTEFFECT* peff)
-{
-    LinuxInputEffectImpl* newEffect = HeapAlloc(GetProcessHeap(), 
-	HEAP_ZERO_MEMORY, sizeof(LinuxInputEffectImpl));
-    DWORD type = typeFromGUID(rguid);
-
-    newEffect->IDirectInputEffect_iface.lpVtbl = &LinuxInputEffectVtbl;
-    newEffect->ref = 1;
-    newEffect->guid = *rguid;
-    newEffect->fd = fd;
-    newEffect->gain = 0xFFFF;
-
-    /* set the type.  this cannot be changed over the effect's life. */
-    switch (type) {
-	case DIEFT_PERIODIC: 
-	    newEffect->effect.type = FF_PERIODIC;
-	    if (IsEqualGUID(rguid, &GUID_Sine)) {
-		newEffect->effect.u.periodic.waveform = FF_SINE;
-	    } else if (IsEqualGUID(rguid, &GUID_Triangle)) {
-                newEffect->effect.u.periodic.waveform = FF_TRIANGLE;
-            } else if (IsEqualGUID(rguid, &GUID_Square)) {
-                newEffect->effect.u.periodic.waveform = FF_SQUARE;
-            } else if (IsEqualGUID(rguid, &GUID_SawtoothUp)) {
-                newEffect->effect.u.periodic.waveform = FF_SAW_UP;
-            } else if (IsEqualGUID(rguid, &GUID_SawtoothDown)) {
-                newEffect->effect.u.periodic.waveform = FF_SAW_DOWN;
-	    }
-	    break;
-	case DIEFT_CONSTANTFORCE: 
-            newEffect->effect.type = FF_CONSTANT;
-	    break;
-	case DIEFT_RAMPFORCE: 
-	    newEffect->effect.type = FF_RAMP;
-	    break;
-	case DIEFT_CONDITION: 
-	    if (IsEqualGUID(rguid, &GUID_Spring)) {
-		newEffect->effect.type = FF_SPRING;
-            } else if (IsEqualGUID(rguid, &GUID_Friction)) {
-		newEffect->effect.type = FF_FRICTION;
-            } else if (IsEqualGUID(rguid, &GUID_Inertia)) {
-		newEffect->effect.type = FF_INERTIA;
-            } else if (IsEqualGUID(rguid, &GUID_Damper)) {
-		newEffect->effect.type = FF_DAMPER;
-	    }
-	    break;
-	case DIEFT_CUSTOMFORCE:
-	    FIXME("Custom forces are not supported.\n");
-	    HeapFree(GetProcessHeap(), 0, newEffect);
-	    return DIERR_INVALIDPARAM;
-	default:
-            FIXME("Unknown force type 0x%x.\n", type);
-            HeapFree(GetProcessHeap(), 0, newEffect);
-	    return DIERR_INVALIDPARAM;
-    }
-
-    /* mark as non-uploaded */
-    newEffect->effect.id = -1;
-
-    newEffect->entry = parent_list_entry;
-
-    *peff = &newEffect->IDirectInputEffect_iface;
-
-    TRACE("Creating linux input system effect (%p) with guid %s\n", 
-	  *peff, _dump_dinput_GUID(rguid));
-
-    return DI_OK;
-}
-
-DECLSPEC_HIDDEN HRESULT linuxinput_get_info_W(
-	int fd,
-	REFGUID rguid,
-	LPDIEFFECTINFOW info)
-{
-    DWORD type = typeFromGUID(rguid);
-
-    TRACE("(%d, %s, %p) type=%d\n", fd, _dump_dinput_GUID(rguid), info, type);
-
-    if (!info) return E_POINTER;
-
-    if (info->dwSize != sizeof(DIEFFECTINFOW)) return DIERR_INVALIDPARAM;
-
-    info->guid = *rguid;
-
-    info->dwEffType = type;
-    /* the event device API does not support querying for all these things
-     * therefore we assume that we have support for them
-     * that's not as dangerous as it sounds, since drivers are allowed to
-     * ignore parameters they claim to support anyway */
-    info->dwEffType |= DIEFT_DEADBAND | DIEFT_FFATTACK | DIEFT_FFFADE
-                    | DIEFT_POSNEGCOEFFICIENTS | DIEFT_POSNEGSATURATION
-                    | DIEFT_SATURATION | DIEFT_STARTDELAY; 
-
-    /* again, assume we have support for everything */
-    info->dwStaticParams = DIEP_ALLPARAMS;
-    info->dwDynamicParams = info->dwStaticParams;
-
-    /* yes, this is windows behavior (print the GUID_Name for name) */
-    MultiByteToWideChar(CP_ACP, 0, _dump_dinput_GUID(rguid), -1, 
-                        info->tszName, MAX_PATH);
-
-    return DI_OK;
-}
-
-static const IDirectInputEffectVtbl LinuxInputEffectVtbl = {
-    LinuxInputEffectImpl_QueryInterface,
-    LinuxInputEffectImpl_AddRef,
-    LinuxInputEffectImpl_Release,
-    LinuxInputEffectImpl_Initialize,
-    LinuxInputEffectImpl_GetEffectGuid,
-    LinuxInputEffectImpl_GetParameters,
-    LinuxInputEffectImpl_SetParameters,
-    LinuxInputEffectImpl_Start,
-    LinuxInputEffectImpl_Stop,
-    LinuxInputEffectImpl_GetEffectStatus,
-    LinuxInputEffectImpl_Download,
-    LinuxInputEffectImpl_Unload,
-    LinuxInputEffectImpl_Escape
-};
-
-#endif /* HAVE_STRUCT_FF_EFFECT_DIRECTION */
diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c
deleted file mode 100644
index afebaa022b7..00000000000
--- a/dlls/dinput/joystick.c
+++ /dev/null
@@ -1,962 +0,0 @@
-/*  DirectInput Generic Joystick device
- *
- * Copyright 1998 Marcus Meissner
- * Copyright 1998,1999 Lionel Ulmer
- * Copyright 2000-2001 TransGaming Technologies Inc.
- * Copyright 2009 Aric Stewart, CodeWeavers
- *
- * 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
- */
-
-/*
- * To Do:
- *	dead zone
- *	force feedback
- */
-
-#include <stdio.h>
-
-#include "joystick_private.h"
-#include "wine/debug.h"
-#include "winreg.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(dinput);
-
-#define VID_MICROSOFT 0x045e
-
-static const WORD PID_XBOX_CONTROLLERS[] =  {
-    0x0202, /* Xbox Controller */
-    0x0285, /* Xbox Controller S */
-    0x0289, /* Xbox Controller S */
-    0x028e, /* Xbox360 Controller */
-    0x028f, /* Xbox360 Wireless Controller */
-    0x02d1, /* Xbox One Controller */
-    0x02dd, /* Xbox One Controller (Covert Forces/Firmware 2015) */
-    0x02e0, /* Xbox One X Controller */
-    0x02e3, /* Xbox One Elite Controller */
-    0x02e6, /* Wireless XBox Controller Dongle */
-    0x02ea, /* Xbox One S Controller */
-    0x02fd, /* Xbox One S Controller (Firmware 2017) */
-    0x0719, /* Xbox 360 Wireless Adapter */
-};
-
-static inline JoystickGenericImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface)
-{
-    return CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8W_iface), JoystickGenericImpl, base);
-}
-
-DWORD typeFromGUID(REFGUID guid)
-{
-    if (IsEqualGUID(guid, &GUID_ConstantForce)) {
-        return DIEFT_CONSTANTFORCE;
-    } else if (IsEqualGUID(guid, &GUID_Square)
-            || IsEqualGUID(guid, &GUID_Sine)
-            || IsEqualGUID(guid, &GUID_Triangle)
-            || IsEqualGUID(guid, &GUID_SawtoothUp)
-            || IsEqualGUID(guid, &GUID_SawtoothDown)) {
-        return DIEFT_PERIODIC;
-    } else if (IsEqualGUID(guid, &GUID_RampForce)) {
-        return DIEFT_RAMPFORCE;
-    } else if (IsEqualGUID(guid, &GUID_Spring)
-            || IsEqualGUID(guid, &GUID_Damper)
-            || IsEqualGUID(guid, &GUID_Inertia)
-            || IsEqualGUID(guid, &GUID_Friction)) {
-        return DIEFT_CONDITION;
-    } else if (IsEqualGUID(guid, &GUID_CustomForce)) {
-        return DIEFT_CUSTOMFORCE;
-    } else {
-        WARN("GUID (%s) is not a known force type\n", _dump_dinput_GUID(guid));
-        return 0;
-    }
-}
-
-DWORD get_device_type(DWORD version, BOOL is_joystick)
-{
-    if (is_joystick)
-        return version >= 0x0800 ? DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8) :
-                    DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
-
-    return version >= 0x0800 ? DI8DEVTYPE_GAMEPAD | (DI8DEVTYPEJOYSTICK_STANDARD << 8) :
-                DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_GAMEPAD << 8);
-}
-
-static void _dump_DIEFFECT_flags(DWORD dwFlags)
-{
-    if (TRACE_ON(dinput)) {
-        unsigned int   i;
-        static const struct {
-            DWORD       mask;
-            const char  *name;
-        } flags[] = {
-#define FE(x) { x, #x}
-            FE(DIEFF_CARTESIAN),
-            FE(DIEFF_OBJECTIDS),
-            FE(DIEFF_OBJECTOFFSETS),
-            FE(DIEFF_POLAR),
-            FE(DIEFF_SPHERICAL)
-#undef FE
-        };
-        for (i = 0; i < ARRAY_SIZE(flags); i++)
-            if (flags[i].mask & dwFlags)
-                TRACE("%s ", flags[i].name);
-        TRACE("\n");
-    }
-}
-
-static void _dump_DIENVELOPE(LPCDIENVELOPE env)
-{
-    if (env->dwSize != sizeof(DIENVELOPE)) {
-        WARN("Non-standard DIENVELOPE structure size %d.\n", env->dwSize);
-    }
-    TRACE("Envelope has attack (level: %d time: %d), fade (level: %d time: %d)\n",
-          env->dwAttackLevel, env->dwAttackTime, env->dwFadeLevel, env->dwFadeTime);
-}
-
-static void _dump_DICONSTANTFORCE(LPCDICONSTANTFORCE frc)
-{
-    TRACE("Constant force has magnitude %d\n", frc->lMagnitude);
-}
-
-static void _dump_DIPERIODIC(LPCDIPERIODIC frc)
-{
-    TRACE("Periodic force has magnitude %d, offset %d, phase %d, period %d\n",
-          frc->dwMagnitude, frc->lOffset, frc->dwPhase, frc->dwPeriod);
-}
-
-static void _dump_DIRAMPFORCE(LPCDIRAMPFORCE frc)
-{
-    TRACE("Ramp force has start %d, end %d\n",
-          frc->lStart, frc->lEnd);
-}
-
-static void _dump_DICONDITION(LPCDICONDITION frc)
-{
-    TRACE("Condition has offset %d, pos/neg coefficients %d and %d, pos/neg saturations %d and %d, deadband %d\n",
-          frc->lOffset, frc->lPositiveCoefficient, frc->lNegativeCoefficient,
-          frc->dwPositiveSaturation, frc->dwNegativeSaturation, frc->lDeadBand);
-}
-
-static void _dump_DICUSTOMFORCE(LPCDICUSTOMFORCE frc)
-{
-    unsigned int i;
-    TRACE("Custom force uses %d channels, sample period %d.  Has %d samples at %p.\n",
-          frc->cChannels, frc->dwSamplePeriod, frc->cSamples, frc->rglForceData);
-    if (frc->cSamples % frc->cChannels != 0)
-        WARN("Custom force has a non-integral samples-per-channel count!\n");
-    if (TRACE_ON(dinput)) {
-        TRACE("Custom force data (time aligned, axes in order):\n");
-        for (i = 1; i <= frc->cSamples; ++i) {
-            TRACE("%d ", frc->rglForceData[i]);
-            if (i % frc->cChannels == 0)
-                TRACE("\n");
-        }
-    }
-}
-
-void dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid, DWORD dwFlags)
-{
-    DWORD type = typeFromGUID(guid);
-    unsigned int i;
-
-    TRACE("Dumping DIEFFECT structure:\n");
-    TRACE("  - dwSize: %d\n", eff->dwSize);
-    if ((eff->dwSize != sizeof(DIEFFECT)) && (eff->dwSize != sizeof(DIEFFECT_DX5))) {
-        WARN("Non-standard DIEFFECT structure size %d\n", eff->dwSize);
-    }
-    TRACE("  - dwFlags: %d\n", eff->dwFlags);
-    TRACE("    ");
-    _dump_DIEFFECT_flags(eff->dwFlags);
-    TRACE("  - dwDuration: %d\n", eff->dwDuration);
-    TRACE("  - dwGain: %d\n", eff->dwGain);
-
-    if (eff->dwGain > 10000)
-        WARN("dwGain is out of range (>10,000)\n");
-
-    TRACE("  - dwTriggerButton: %d\n", eff->dwTriggerButton);
-    TRACE("  - dwTriggerRepeatInterval: %d\n", eff->dwTriggerRepeatInterval);
-    TRACE("  - rglDirection: %p\n", eff->rglDirection);
-    if (dwFlags & DIEP_DIRECTION && eff->rglDirection) {
-        TRACE("    ");
-        for (i = 0; i < eff->cAxes; ++i)
-            TRACE("%d ", eff->rglDirection[i]);
-        TRACE("\n");
-    }
-    TRACE("  - cbTypeSpecificParams: %d\n", eff->cbTypeSpecificParams);
-    TRACE("  - lpvTypeSpecificParams: %p\n", eff->lpvTypeSpecificParams);
-
-    /* Only trace some members if dwFlags indicates they have data */
-    if (dwFlags & DIEP_AXES) {
-        TRACE("  - cAxes: %d\n", eff->cAxes);
-        TRACE("  - rgdwAxes: %p\n", eff->rgdwAxes);
-
-        if (TRACE_ON(dinput) && eff->rgdwAxes) {
-            TRACE("    ");
-            for (i = 0; i < eff->cAxes; ++i)
-                TRACE("%d ", eff->rgdwAxes[i]);
-            TRACE("\n");
-        }
-    }
-
-    if (dwFlags & DIEP_ENVELOPE) {
-        TRACE("  - lpEnvelope: %p\n", eff->lpEnvelope);
-        if (eff->lpEnvelope != NULL)
-            _dump_DIENVELOPE(eff->lpEnvelope);
-    }
-
-    if (eff->dwSize > sizeof(DIEFFECT_DX5))
-        TRACE("  - dwStartDelay: %d\n", eff->dwStartDelay);
-
-    if (type == DIEFT_CONSTANTFORCE) {
-        if (eff->cbTypeSpecificParams != sizeof(DICONSTANTFORCE)) {
-            WARN("Effect claims to be a constant force but the type-specific params are the wrong size!\n");
-        } else if (!eff->lpvTypeSpecificParams) {
-            WARN("Size of type-specific params is correct but pointer is NULL!\n");
-        } else {
-            _dump_DICONSTANTFORCE(eff->lpvTypeSpecificParams);
-        }
-    } else if (type == DIEFT_PERIODIC) {
-        if (eff->cbTypeSpecificParams != sizeof(DIPERIODIC)) {
-            WARN("Effect claims to be a periodic force but the type-specific params are the wrong size!\n");
-        } else if (!eff->lpvTypeSpecificParams) {
-            WARN("Size of type-specific params is correct but pointer is NULL!\n");
-        } else {
-            _dump_DIPERIODIC(eff->lpvTypeSpecificParams);
-        }
-    } else if (type == DIEFT_RAMPFORCE) {
-        if (eff->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) {
-            WARN("Effect claims to be a ramp force but the type-specific params are the wrong size!\n");
-        } else if (!eff->lpvTypeSpecificParams) {
-            WARN("Size of type-specific params is correct but pointer is NULL!\n");
-        } else {
-            _dump_DIRAMPFORCE(eff->lpvTypeSpecificParams);
-        }
-    } else if (type == DIEFT_CONDITION) {
-        if (eff->cbTypeSpecificParams == sizeof(DICONDITION) && eff->lpvTypeSpecificParams) {
-            _dump_DICONDITION(eff->lpvTypeSpecificParams);
-        } else if (eff->cbTypeSpecificParams == 2 * sizeof(DICONDITION) && eff->lpvTypeSpecificParams) {
-            DICONDITION *condition = eff->lpvTypeSpecificParams;
-            _dump_DICONDITION(&condition[0]);
-            _dump_DICONDITION(&condition[1]);
-        } else {
-            WARN("Effect claims to be a condition but the type-specific params are the wrong size or NULL!\n");
-        }
-    } else if (type == DIEFT_CUSTOMFORCE) {
-        if (eff->cbTypeSpecificParams != sizeof(DICUSTOMFORCE)) {
-            WARN("Effect claims to be a custom force but the type-specific params are the wrong size!\n");
-        } else if (!eff->lpvTypeSpecificParams) {
-            WARN("Size of type-specific params is correct but pointer is NULL!\n");
-        } else {
-            _dump_DICUSTOMFORCE(eff->lpvTypeSpecificParams);
-        }
-    }
-}
-
-BOOL device_disabled_registry(const char* name)
-{
-    DIDEVICEINSTANCEW instance;
-
-    MultiByteToWideChar( CP_ACP, 0, name, -1, instance.tszInstanceName, MAX_PATH );
-    return device_instance_is_disabled( &instance, NULL );
-}
-
-BOOL is_xinput_device(const DIDEVCAPS *devcaps, WORD vid, WORD pid)
-{
-    int i;
-
-    if (vid == VID_MICROSOFT)
-    {
-        for (i = 0; i < ARRAY_SIZE(PID_XBOX_CONTROLLERS); i++)
-            if (pid == PID_XBOX_CONTROLLERS[i]) return TRUE;
-    }
-
-    return (devcaps->dwAxes == 6 && devcaps->dwButtons >= 14);
-}
-
-/******************************************************************************
-  *     SetProperty : change input device properties
-  */
-HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIPROPHEADER ph)
-{
-    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
-    DWORD i;
-    ObjProps remap_props;
-
-    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 (IS_DIPROP(rguid)) {
-        switch (LOWORD(rguid)) {
-        case (DWORD_PTR)DIPROP_RANGE: {
-            LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph;
-            if (ph->dwHow == DIPH_DEVICE) {
-
-                /* Many games poll the joystick immediately after setting the range
-                 * for calibration purposes, so the old values need to be remapped
-                 * to the new range before it does so */
-
-                TRACE("proprange(%d,%d) all\n", pr->lMin, pr->lMax);
-                for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++) {
-
-                    remap_props.lDevMin = This->props[i].lMin;
-                    remap_props.lDevMax = This->props[i].lMax;
-
-                    remap_props.lDeadZone = This->props[i].lDeadZone;
-                    remap_props.lSaturation = This->props[i].lSaturation;
-
-                    remap_props.lMin = pr->lMin;
-                    remap_props.lMax = pr->lMax;
-
-                    switch (This->base.data_format.wine_df->rgodf[i].dwOfs) {
-                    case DIJOFS_X        : This->js.lX  = joystick_map_axis(&remap_props, This->js.lX); break;
-                    case DIJOFS_Y        : This->js.lY  = joystick_map_axis(&remap_props, This->js.lY); break;
-                    case DIJOFS_Z        : This->js.lZ  = joystick_map_axis(&remap_props, This->js.lZ); break;
-                    case DIJOFS_RX       : This->js.lRx = joystick_map_axis(&remap_props, This->js.lRx); break;
-                    case DIJOFS_RY       : This->js.lRy = joystick_map_axis(&remap_props, This->js.lRy); break;
-                    case DIJOFS_RZ       : This->js.lRz = joystick_map_axis(&remap_props, This->js.lRz); break;
-                    case DIJOFS_SLIDER(0): This->js.rglSlider[0] = joystick_map_axis(&remap_props, This->js.rglSlider[0]); break;
-                    case DIJOFS_SLIDER(1): This->js.rglSlider[1] = joystick_map_axis(&remap_props, This->js.rglSlider[1]); break;
-	            default: break;
-                    }
-
-                    This->props[i].lMin = pr->lMin;
-                    This->props[i].lMax = pr->lMax;
-                }
-            } else {
-                int obj = find_property(&This->base.data_format, ph);
-
-                TRACE("proprange(%d,%d) obj=%d\n", pr->lMin, pr->lMax, obj);
-                if (obj >= 0) {
-
-                    remap_props.lDevMin = This->props[obj].lMin;
-                    remap_props.lDevMax = This->props[obj].lMax;
-
-                    remap_props.lDeadZone = This->props[obj].lDeadZone;
-                    remap_props.lSaturation = This->props[obj].lSaturation;
-
-                    remap_props.lMin = pr->lMin;
-                    remap_props.lMax = pr->lMax;
-
-                    switch (This->base.data_format.wine_df->rgodf[obj].dwOfs) {
-                    case DIJOFS_X        : This->js.lX  = joystick_map_axis(&remap_props, This->js.lX); break;
-                    case DIJOFS_Y        : This->js.lY  = joystick_map_axis(&remap_props, This->js.lY); break;
-                    case DIJOFS_Z        : This->js.lZ  = joystick_map_axis(&remap_props, This->js.lZ); break;
-                    case DIJOFS_RX       : This->js.lRx = joystick_map_axis(&remap_props, This->js.lRx); break;
-                    case DIJOFS_RY       : This->js.lRy = joystick_map_axis(&remap_props, This->js.lRy); break;
-                    case DIJOFS_RZ       : This->js.lRz = joystick_map_axis(&remap_props, This->js.lRz); break;
-                    case DIJOFS_SLIDER(0): This->js.rglSlider[0] = joystick_map_axis(&remap_props, This->js.rglSlider[0]); break;
-                    case DIJOFS_SLIDER(1): This->js.rglSlider[1] = joystick_map_axis(&remap_props, This->js.rglSlider[1]); break;
-		    default: break;
-                    }
-
-                    This->props[obj].lMin = pr->lMin;
-                    This->props[obj].lMax = pr->lMax;
-                    return DI_OK;
-                }
-            }
-            break;
-        }
-        case (DWORD_PTR)DIPROP_DEADZONE: {
-            LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
-            if (ph->dwHow == DIPH_DEVICE) {
-                TRACE("deadzone(%d) all\n", pd->dwData);
-                for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++)
-                    This->props[i].lDeadZone  = pd->dwData;
-            } else {
-                int obj = find_property(&This->base.data_format, ph);
-
-                TRACE("deadzone(%d) obj=%d\n", pd->dwData, obj);
-                if (obj >= 0) {
-                    This->props[obj].lDeadZone  = pd->dwData;
-                    return DI_OK;
-                }
-            }
-            break;
-        }
-        case (DWORD_PTR)DIPROP_SATURATION: {
-            LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
-            if (ph->dwHow == DIPH_DEVICE) {
-                TRACE("saturation(%d) all\n", pd->dwData);
-                for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++)
-                    This->props[i].lSaturation = pd->dwData;
-            } else {
-                int obj = find_property(&This->base.data_format, ph);
-
-                TRACE("saturation(%d) obj=%d\n", pd->dwData, obj);
-                if (obj >= 0) {
-                    This->props[obj].lSaturation = pd->dwData;
-                    return DI_OK;
-                }
-            }
-            break;
-        }
-        case (DWORD_PTR)DIPROP_CALIBRATIONMODE: {
-          LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
-          FIXME("DIPROP_CALIBRATIONMODE(%d)\n", pd->dwData);
-          break;
-        }
-        default:
-            return IDirectInputDevice2WImpl_SetProperty(iface, rguid, ph);
-        }
-    }
-
-    return DI_OK;
-}
-
-#define DEBUG_TYPE(x) case (x): str = #x; break
-void _dump_DIDEVCAPS(const DIDEVCAPS *lpDIDevCaps)
-{
-    int type = GET_DIDEVICE_TYPE(lpDIDevCaps->dwDevType);
-    const char *str, *hid = "";
-    TRACE("dwSize: %d\n", lpDIDevCaps->dwSize);
-    TRACE("dwFlags: %08x\n", lpDIDevCaps->dwFlags);
-    switch(type)
-    {
-        /* Direct X <= 7 definitions */
-        DEBUG_TYPE(DIDEVTYPE_DEVICE);
-        DEBUG_TYPE(DIDEVTYPE_MOUSE);
-        DEBUG_TYPE(DIDEVTYPE_KEYBOARD);
-        DEBUG_TYPE(DIDEVTYPE_JOYSTICK);
-        /* Direct X >= 8 definitions */
-        DEBUG_TYPE(DI8DEVTYPE_DEVICE);
-        DEBUG_TYPE(DI8DEVTYPE_MOUSE);
-        DEBUG_TYPE(DI8DEVTYPE_KEYBOARD);
-        DEBUG_TYPE(DI8DEVTYPE_JOYSTICK);
-        DEBUG_TYPE(DI8DEVTYPE_GAMEPAD);
-        DEBUG_TYPE(DI8DEVTYPE_DRIVING);
-        DEBUG_TYPE(DI8DEVTYPE_FLIGHT);
-        DEBUG_TYPE(DI8DEVTYPE_1STPERSON);
-        DEBUG_TYPE(DI8DEVTYPE_DEVICECTRL);
-        DEBUG_TYPE(DI8DEVTYPE_SCREENPOINTER);
-        DEBUG_TYPE(DI8DEVTYPE_REMOTE);
-        DEBUG_TYPE(DI8DEVTYPE_SUPPLEMENTAL);
-        default: str = "UNKNOWN";
-    }
-
-    if (lpDIDevCaps->dwDevType & DIDEVTYPE_HID)
-        hid = " (HID)";
-
-    TRACE("dwDevType: %08x %s%s\n", lpDIDevCaps->dwDevType, str, hid);
-    TRACE("dwAxes: %d\n", lpDIDevCaps->dwAxes);
-    TRACE("dwButtons: %d\n", lpDIDevCaps->dwButtons);
-    TRACE("dwPOVs: %d\n", lpDIDevCaps->dwPOVs);
-    if (lpDIDevCaps->dwSize > sizeof(DIDEVCAPS_DX3)) {
-        TRACE("dwFFSamplePeriod: %d\n", lpDIDevCaps->dwFFSamplePeriod);
-        TRACE("dwFFMinTimeResolution: %d\n", lpDIDevCaps->dwFFMinTimeResolution);
-        TRACE("dwFirmwareRevision: %d\n", lpDIDevCaps->dwFirmwareRevision);
-        TRACE("dwHardwareRevision: %d\n", lpDIDevCaps->dwHardwareRevision);
-        TRACE("dwFFDriverVersion: %d\n", lpDIDevCaps->dwFFDriverVersion);
-    }
-}
-#undef DEBUG_TYPE
-
-HRESULT WINAPI JoystickWGenericImpl_GetCapabilities(LPDIRECTINPUTDEVICE8W iface, LPDIDEVCAPS lpDIDevCaps)
-{
-    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
-    int size;
-
-    TRACE("%p->(%p)\n",This,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;
-}
-
-
-ULONG WINAPI JoystickWGenericImpl_Release(LPDIRECTINPUTDEVICE8W iface)
-{
-    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
-    void *axis_map = This->axis_map;
-    ULONG res = IDirectInputDevice2WImpl_Release(iface);
-    if (!res) HeapFree(GetProcessHeap(), 0, axis_map);
-    return res;
-}
-
-
-/******************************************************************************
-  *     GetObjectInfo : get object info
-  */
-HRESULT WINAPI JoystickWGenericImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
-        LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow)
-{
-    static const WCHAR axisW[] = {'A','x','i','s',' ','%','d',0};
-    static const WCHAR povW[] = {'P','O','V',' ','%','d',0};
-    static const WCHAR buttonW[] = {'B','u','t','t','o','n',' ','%','d',0};
-    HRESULT res;
-
-    res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
-    if (res != DI_OK) return res;
-
-    if (pdidoi->dwType & DIDFT_AXIS) {
-        sprintfW(pdidoi->tszName, axisW, DIDFT_GETINSTANCE(pdidoi->dwType));
-        pdidoi->dwFlags |= DIDOI_ASPECTPOSITION;
-    } else if (pdidoi->dwType & DIDFT_POV)
-        sprintfW(pdidoi->tszName, povW, DIDFT_GETINSTANCE(pdidoi->dwType));
-    else if (pdidoi->dwType & DIDFT_BUTTON)
-        sprintfW(pdidoi->tszName, buttonW, DIDFT_GETINSTANCE(pdidoi->dwType));
-
-    _dump_OBJECTINSTANCEW(pdidoi);
-    return res;
-}
-
-/******************************************************************************
-  *     GetProperty : get input device properties
-  */
-HRESULT WINAPI JoystickWGenericImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
-{
-    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(%p,%s,%p)\n", This, debugstr_guid(rguid), pdiph);
-
-    if (TRACE_ON(dinput))
-        _dump_DIPROPHEADER(pdiph);
-
-    if (IS_DIPROP(rguid)) {
-        switch (LOWORD(rguid)) {
-        case (DWORD_PTR) DIPROP_RANGE: {
-            LPDIPROPRANGE pr = (LPDIPROPRANGE)pdiph;
-            int obj = find_property(&This->base.data_format, 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(%d, %d) obj=%d\n", pr->lMin, pr->lMax, obj);
-                return DI_OK;
-            }
-            break;
-        }
-        case (DWORD_PTR) DIPROP_DEADZONE: {
-            LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-            int obj = find_property(&This->base.data_format, pdiph);
-
-            if (obj >= 0) {
-                pd->dwData = This->props[obj].lDeadZone;
-                TRACE("deadzone(%d) obj=%d\n", pd->dwData, obj);
-                return DI_OK;
-            }
-            break;
-        }
-        case (DWORD_PTR) DIPROP_SATURATION: {
-            LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-            int obj = find_property(&This->base.data_format, pdiph);
-
-            if (obj >= 0) {
-                pd->dwData = This->props[obj].lSaturation;
-                TRACE("saturation(%d) obj=%d\n", pd->dwData, obj);
-                return DI_OK;
-            }
-            break;
-        }
-        case (DWORD_PTR) DIPROP_PRODUCTNAME:
-        case (DWORD_PTR) DIPROP_INSTANCENAME: {
-            DIPROPSTRING *ps = (DIPROPSTRING*) pdiph;
-            DIDEVICEINSTANCEW didev;
-
-            didev.dwSize = sizeof(didev);
-
-            IDirectInputDevice_GetDeviceInfo(iface, &didev);
-            if (LOWORD(rguid) == (DWORD_PTR) DIPROP_PRODUCTNAME)
-                lstrcpynW(ps->wsz, didev.tszProductName, MAX_PATH);
-            else
-                lstrcpynW(ps->wsz, didev.tszInstanceName, MAX_PATH);
-
-            return DI_OK;
-        }
-        default:
-            return IDirectInputDevice2WImpl_GetProperty(iface, rguid, pdiph);
-        }
-    }
-
-    return DI_OK;
-}
-
-/******************************************************************************
-  *     GetDeviceInfo : get information about a device's identity
-  */
-HRESULT WINAPI JoystickWGenericImpl_GetDeviceInfo(
-    LPDIRECTINPUTDEVICE8W iface,
-    LPDIDEVICEINSTANCEW pdidi)
-{
-    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
-    CHAR buffer[MAX_PATH];
-    DIPROPDWORD pd;
-    DWORD index = 0;
-
-    TRACE("(%p,%p)\n", iface, pdidi);
-
-    if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) &&
-        (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW))) {
-        WARN("invalid parameter: pdidi->dwSize = %d\n", pdidi->dwSize);
-        return DIERR_INVALIDPARAM;
-    }
-
-    /* Try to get joystick index */
-    pd.diph.dwSize = sizeof(pd);
-    pd.diph.dwHeaderSize = sizeof(pd.diph);
-    pd.diph.dwObj = 0;
-    pd.diph.dwHow = DIPH_DEVICE;
-    if (SUCCEEDED(IDirectInputDevice2_GetProperty(iface, DIPROP_JOYSTICKID, &pd.diph)))
-        index = pd.dwData;
-
-    /* Return joystick */
-    pdidi->guidInstance = This->base.guid;
-    pdidi->guidProduct = This->guidProduct;
-    /* we only support traditional joysticks for now */
-    pdidi->dwDevType = This->devcaps.dwDevType;
-    snprintf(buffer, sizeof(buffer), "Joystick %d", index);
-    MultiByteToWideChar(CP_ACP, 0, buffer, -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;
-}
-
-HRESULT WINAPI JoystickWGenericImpl_Poll(LPDIRECTINPUTDEVICE8W iface)
-{
-    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(%p)\n",This);
-
-    if (!This->base.acquired) {
-        WARN("not acquired\n");
-        return DIERR_NOTACQUIRED;
-    }
-
-    This->joy_polldev( iface );
-    return DI_OK;
-}
-
-/******************************************************************************
-  *     GetDeviceState : returns the "state" of the joystick.
-  *
-  */
-HRESULT WINAPI JoystickWGenericImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W iface, DWORD len, LPVOID ptr)
-{
-    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(%p,0x%08x,%p)\n", This, len, ptr);
-
-    if (!This->base.acquired) {
-        WARN("not acquired\n");
-        return DIERR_NOTACQUIRED;
-    }
-
-    /* update joystick state */
-    This->joy_polldev( iface );
-
-    /* convert and copy data to user supplied buffer */
-    fill_DataFormat(ptr, len, &This->js, &This->base.data_format);
-
-    return DI_OK;
-}
-
-HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
-                                                   LPDIACTIONFORMATW lpdiaf,
-                                                   LPCWSTR lpszUserName,
-                                                   DWORD dwFlags)
-{
-    static const DWORD object_types[] = { DIDFT_AXIS, DIDFT_BUTTON };
-    static const DWORD type_map[] = { DIDFT_RELAXIS, DIDFT_PSHBUTTON };
-    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
-    unsigned int i, j;
-    BOOL has_actions = FALSE;
-
-    FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags);
-
-    for (i=0; i < lpdiaf->dwNumActions; i++)
-    {
-        DWORD inst = (0x000000ff & (lpdiaf->rgoAction[i].dwSemantic)) - 1;
-        DWORD type = 0x000000ff & (lpdiaf->rgoAction[i].dwSemantic >> 8);
-        DWORD genre = 0xff000000 & lpdiaf->rgoAction[i].dwSemantic;
-
-        /* Don't touch a user configured action */
-        if (lpdiaf->rgoAction[i].dwHow == DIAH_USERCONFIG) continue;
-
-        /* Only consider actions of the right genre */
-        if (lpdiaf->dwGenre != genre && genre != DIGENRE_ANY) continue;
-
-        for (j = 0; j < ARRAY_SIZE(object_types); j++)
-        {
-            if (type & object_types[j])
-            {
-                /* Ensure that the object exists */
-                LPDIOBJECTDATAFORMAT odf = dataformat_to_odf_by_type(This->base.data_format.wine_df, inst, object_types[j]);
-
-                if (odf != NULL)
-                {
-                    lpdiaf->rgoAction[i].dwObjID = type_map[j] | (0x0000ff00 & (inst << 8));
-                    lpdiaf->rgoAction[i].guidInstance = This->base.guid;
-                    lpdiaf->rgoAction[i].dwHow = DIAH_DEFAULT;
-
-                    has_actions = TRUE;
-
-                    /* No need to try other types if the action was already mapped */
-                    break;
-                }
-            }
-        }
-    }
-
-    if (!has_actions) return DI_NOEFFECT;
-
-    return IDirectInputDevice8WImpl_BuildActionMap(iface, lpdiaf, lpszUserName, dwFlags);
-}
-
-HRESULT WINAPI JoystickWGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
-                                                 LPDIACTIONFORMATW lpdiaf,
-                                                 LPCWSTR lpszUserName,
-                                                 DWORD dwFlags)
-{
-    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags);
-
-    return _set_action_map(iface, lpdiaf, lpszUserName, dwFlags, This->base.data_format.wine_df);
-}
-
-/*
- * This maps the read value (from the input event) to a value in the
- * 'wanted' range.
- * Notes:
- *   Dead zone is in % multiplied by a 100 (range 0..10000)
- */
-LONG joystick_map_axis(ObjProps *props, int val)
-{
-    LONG ret;
-    LONG dead_zone = MulDiv( props->lDeadZone, props->lDevMax - props->lDevMin, 10000 );
-    LONG dev_range = props->lDevMax - props->lDevMin - dead_zone;
-
-    /* Center input */
-    val -= (props->lDevMin + props->lDevMax) / 2;
-
-    /* Remove dead zone */
-    if (abs( val ) <= dead_zone / 2)
-        val = 0;
-    else
-        val = val < 0 ? val + dead_zone / 2 : val - dead_zone / 2;
-
-    /* Scale and map the value from the device range into the required range */
-    ret = MulDiv( val, props->lMax - props->lMin, dev_range ) +
-          (props->lMin + props->lMax) / 2;
-
-    /* Clamp in case or rounding errors */
-    if      (ret > props->lMax) ret = props->lMax;
-    else if (ret < props->lMin) ret = props->lMin;
-
-    TRACE( "(%d <%d> %d) -> (%d <%d> %d): val=%d ret=%d\n",
-           props->lDevMin, dead_zone, props->lDevMax,
-           props->lMin, props->lDeadZone, props->lMax,
-           val, ret );
-
-    return ret;
-}
-
-/*
- * Maps POV x & y event values to a DX "clock" position:
- *         0
- *   31500    4500
- * 27000  -1    9000
- *   22500   13500
- *       18000
- */
-DWORD joystick_map_pov(const POINTL *p)
-{
-    if (p->x > 0)
-        return p->y < 0 ?  4500 : !p->y ?  9000 : 13500;
-    else if (p->x < 0)
-        return p->y < 0 ? 31500 : !p->y ? 27000 : 22500;
-    else
-        return p->y < 0 ?     0 : !p->y ?    -1 : 18000;
-}
-
-static DWORD get_config_key_a( HKEY defkey, HKEY appkey, const char *name, char *buffer, DWORD size )
-{
-    if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
-
-    if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
-
-    return ERROR_FILE_NOT_FOUND;
-}
-
-/*
- * Setup the dinput options.
- */
-
-HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_map)
-{
-    char buffer[MAX_PATH+16];
-    HKEY hkey, appkey;
-    int tokens = 0;
-    int axis = 0;
-    int pov = 0;
-
-    get_app_key(&hkey, &appkey);
-
-    /* get options */
-
-    if (!get_config_key_a( hkey, appkey, "DefaultDeadZone", buffer, sizeof(buffer) ))
-    {
-        This->deadzone = atoi(buffer);
-        TRACE("setting default deadzone to: \"%s\" %d\n", buffer, This->deadzone);
-    }
-
-    This->axis_map = HeapAlloc(GetProcessHeap(), 0, This->device_axis_count * sizeof(int));
-    if (!This->axis_map) return DIERR_OUTOFMEMORY;
-
-    if (!get_config_key_a( hkey, appkey, This->name, buffer, sizeof(buffer) ))
-    {
-        static const char *axis_names[] = {"X", "Y", "Z", "Rx", "Ry", "Rz",
-                                           "Slider1", "Slider2",
-                                           "POV1", "POV2", "POV3", "POV4"};
-        const char *delim = ",";
-        char * ptr;
-        TRACE("\"%s\" = \"%s\"\n", This->name, buffer);
-
-        if ((ptr = strtok(buffer, delim)) != NULL)
-        {
-            do
-            {
-                int i;
-
-                for (i = 0; i < ARRAY_SIZE(axis_names); i++)
-                {
-                    if (!strcmp(ptr, axis_names[i]))
-                    {
-                        if (!strncmp(ptr, "POV", 3))
-                        {
-                            if (pov >= 4)
-                            {
-                                WARN("Only 4 POVs supported - ignoring extra\n");
-                                i = -1;
-                            }
-                            else
-                            {
-                                /* Pov takes two axes */
-                                This->axis_map[tokens++] = i;
-                                pov++;
-                            }
-                        }
-                        else
-                        {
-                            if (axis >= 8)
-                            {
-                                FIXME("Only 8 Axes supported - ignoring extra\n");
-                                i = -1;
-                            }
-                            else
-                                axis++;
-                        }
-                        break;
-                    }
-                }
-
-                if (i == ARRAY_SIZE(axis_names))
-                {
-                    ERR("invalid joystick axis type: \"%s\"\n", ptr);
-                    i = -1;
-                }
-
-                This->axis_map[tokens] = i;
-                tokens++;
-            } while ((ptr = strtok(NULL, delim)) != NULL);
-
-            if (tokens != This->device_axis_count)
-            {
-                ERR("not all joystick axes mapped: %d axes(%d,%d), %d arguments\n",
-                    This->device_axis_count, axis, pov, tokens);
-                while (tokens < This->device_axis_count)
-                {
-                    This->axis_map[tokens] = -1;
-                    tokens++;
-                }
-            }
-        }
-    }
-    else
-    {
-        int i;
-
-        if (default_axis_map)
-        {
-            /* Use default mapping from the driver */
-            for (i = 0; i < This->device_axis_count; i++)
-            {
-                This->axis_map[i] = default_axis_map[i];
-                tokens = default_axis_map[i];
-                if (tokens < 0)
-                    continue;
-                if (tokens < 8)
-                    axis++;
-                else if (tokens < 15)
-                {
-                    i++;
-                    pov++;
-                    This->axis_map[i] = default_axis_map[i];
-                }
-            }
-        }
-        else
-        {
-            /* No config - set default mapping. */
-            for (i = 0; i < This->device_axis_count; i++)
-            {
-                if (i < 8)
-                    This->axis_map[i] = axis++;
-                else if (i < 15)
-                {
-                    This->axis_map[i++] = 8 + pov;
-                    This->axis_map[i  ] = 8 + pov++;
-                }
-                else
-                    This->axis_map[i] = -1;
-            }
-        }
-    }
-    This->devcaps.dwAxes = axis;
-    This->devcaps.dwPOVs = pov;
-
-    if (appkey) RegCloseKey(appkey);
-    if (hkey)   RegCloseKey(hkey);
-
-    return DI_OK;
-}
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index 63193554405..9af4ef8ba3f 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -37,16 +37,16 @@
 #include "dinput.h"
 #include "setupapi.h"
 
-#include "wine/debug.h"
-#include "wine/hid.h"
-
 #include "dinput_private.h"
 #include "device_private.h"
-#include "joystick_private.h"
 
 #include "initguid.h"
 #include "devpkey.h"
 
+#include "wine/unicode.h"
+#include "wine/debug.h"
+#include "wine/hid.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
 
 DEFINE_GUID( GUID_DEVINTERFACE_WINEXINPUT,0x6c53d5fd,0x6480,0x440f,0xb6,0x18,0x47,0x67,0x50,0xc5,0xe1,0xa6 );
diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
deleted file mode 100644
index decd69b1e7e..00000000000
--- a/dlls/dinput/joystick_linux.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/*		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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-#include <fcntl.h>
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#include <errno.h>
-#ifdef HAVE_LINUX_IOCTL_H
-# include <linux/ioctl.h>
-#endif
-#ifdef HAVE_LINUX_JOYSTICK_H
-# include <linux/joystick.h>
-# undef SW_MAX
-#endif
-#ifdef HAVE_SYS_POLL_H
-# include <sys/poll.h>
-#endif
-
-#include "wine/debug.h"
-#include "wine/unicode.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "devguid.h"
-#include "dinput.h"
-
-#include "dinput_private.h"
-#include "device_private.h"
-#include "joystick_private.h"
-
-#ifdef HAVE_LINUX_22_JOYSTICK_API
-
-WINE_DEFAULT_DEBUG_CHANNEL(dinput);
-
-#define JOYDEV_NEW "/dev/input/js"
-#define JOYDEV_OLD "/dev/js"
-#define JOYDEVDRIVER " (js)"
-
-struct JoyDev
-{
-    char device[MAX_PATH];
-    char name[MAX_PATH];
-    GUID guid_product;
-
-    BYTE axis_count;
-    BYTE button_count;
-    int  *dev_axes_map;
-
-    WORD vendor_id, product_id, bus_type;
-
-    BOOL is_joystick;
-};
-
-typedef struct JoystickImpl JoystickImpl;
-static const IDirectInputDevice8WVtbl JoystickWvt;
-struct JoystickImpl
-{
-        struct JoystickGenericImpl generic;
-
-        struct JoyDev                  *joydev;
-
-	/* joystick private */
-	int				joyfd;
-        POINTL                          povs[4];
-};
-
-static inline JoystickImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface)
-{
-    return CONTAINING_RECORD(CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8W_iface),
-           JoystickGenericImpl, base), JoystickImpl, generic);
-}
-
-static const GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
-  0x9e573ed9,
-  0x7734,
-  0x11d2,
-  {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
-};
-
-#define MAX_JOYSTICKS 64
-static INT joystick_devices_count = -1;
-static struct JoyDev *joystick_devices;
-
-static void joy_polldev( IDirectInputDevice8W *iface );
-
-#define SYS_PATH_FORMAT "/sys/class/input/js%d/device/id/%s"
-static BOOL read_sys_id_variable(int index, const char *property, WORD *value)
-{
-    char sys_path[sizeof(SYS_PATH_FORMAT) + 16], id_str[5];
-    int sys_fd;
-    BOOL ret = FALSE;
-
-    sprintf(sys_path, SYS_PATH_FORMAT, index, property);
-    if ((sys_fd = open(sys_path, O_RDONLY)) != -1)
-    {
-        if (read(sys_fd, id_str, 4) == 4)
-        {
-            id_str[4] = '\0';
-            *value = strtol(id_str, NULL, 16);
-            ret = TRUE;
-        }
-
-        close(sys_fd);
-    }
-    return ret;
-}
-#undef SYS_PATH_FORMAT
-
-static INT find_joystick_devices(void)
-{
-    INT i;
-
-    if (joystick_devices_count != -1) return joystick_devices_count;
-
-    joystick_devices_count = 0;
-    for (i = 0; i < MAX_JOYSTICKS; i++)
-    {
-        int fd;
-        struct JoyDev joydev, *new_joydevs;
-        BYTE axes_map[ABS_MAX + 1];
-        SHORT btn_map[KEY_MAX - BTN_MISC + 1];
-        BOOL non_js = FALSE;
-
-        snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_NEW, i);
-        if ((fd = open(joydev.device, O_RDONLY)) == -1)
-        {
-            snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_OLD, i);
-            if ((fd = open(joydev.device, O_RDONLY)) == -1) continue;
-        }
-
-        strcpy(joydev.name, "Wine Joystick");
-#if defined(JSIOCGNAME)
-        if (ioctl(fd, JSIOCGNAME(sizeof(joydev.name) - sizeof(JOYDEVDRIVER)), joydev.name) < 0)
-            WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", joydev.device, strerror(errno));
-#endif
-
-        /* Append driver name */
-        strcat(joydev.name, JOYDEVDRIVER);
-
-        if (device_disabled_registry(joydev.name)) {
-            close(fd);
-            continue;
-        }
-
-#ifdef JSIOCGAXES
-        if (ioctl(fd, JSIOCGAXES, &joydev.axis_count) < 0)
-        {
-            WARN("ioctl(%s,JSIOCGAXES) failed: %s, defaulting to 2\n", joydev.device, strerror(errno));
-            joydev.axis_count = 2;
-        }
-#else
-        WARN("reading number of joystick axes unsupported in this platform, defaulting to 2\n");
-        joydev.axis_count = 2;
-#endif
-#ifdef JSIOCGBUTTONS
-        if (ioctl(fd, JSIOCGBUTTONS, &joydev.button_count) < 0)
-        {
-            WARN("ioctl(%s,JSIOCGBUTTONS) failed: %s, defaulting to 2\n", joydev.device, strerror(errno));
-            joydev.button_count = 2;
-        }
-#else
-        WARN("reading number of joystick buttons unsupported in this platform, defaulting to 2\n");
-        joydev.button_count = 2;
-#endif
-
-        joydev.is_joystick = FALSE;
-        if (ioctl(fd, JSIOCGBTNMAP, btn_map) < 0)
-        {
-            WARN("ioctl(%s,JSIOCGBTNMAP) failed: %s\n", joydev.device, strerror(errno));
-        }
-        else
-        {
-            INT j;
-            /* in lieu of properly reporting HID usage, detect presence of
-             * "joystick buttons" and report those devices as joysticks instead of
-             * gamepads */
-            for (j = 0; !joydev.is_joystick && j < joydev.button_count; j++)
-            {
-                switch (btn_map[j])
-                {
-                case BTN_TRIGGER:
-                case BTN_THUMB:
-                case BTN_THUMB2:
-                case BTN_TOP:
-                case BTN_TOP2:
-                case BTN_PINKIE:
-                case BTN_BASE:
-                case BTN_BASE2:
-                case BTN_BASE3:
-                case BTN_BASE4:
-                case BTN_BASE5:
-                case BTN_BASE6:
-                case BTN_DEAD:
-                    joydev.is_joystick = TRUE;
-                    break;
-                case BTN_MOUSE:
-                case BTN_STYLUS:
-                    non_js = TRUE;
-                    break;
-                default:
-                    break;
-                }
-            }
-        }
-
-        if(non_js)
-        {
-            TRACE("Non-joystick detected. Skipping\n");
-            close(fd);
-            continue;
-        }
-
-        if (ioctl(fd, JSIOCGAXMAP, axes_map) < 0)
-        {
-            WARN("ioctl(%s,JSIOCGAXMAP) failed: %s\n", joydev.device, strerror(errno));
-            joydev.dev_axes_map = NULL;
-        }
-        else
-            if ((joydev.dev_axes_map = HeapAlloc(GetProcessHeap(), 0, joydev.axis_count * sizeof(int))))
-            {
-                INT j, found_axes = 0;
-
-                /* Remap to DI numbers */
-                for (j = 0; j < joydev.axis_count; j++)
-                {
-                    if (axes_map[j] < 8)
-                    {
-                        /* Axis match 1-to-1 */
-                        joydev.dev_axes_map[j] = j;
-                        found_axes++;
-                    }
-                    else if (axes_map[j] <= 10)
-                    {
-                        /* Axes 8 through 10 are Wheel, Gas and Brake,
-                         * remap to 0, 1 and 2
-                         */
-                        joydev.dev_axes_map[j] = axes_map[j] - 8;
-                        found_axes++;
-                    }
-                    else if (axes_map[j] == 16 ||
-                             axes_map[j] == 17)
-                    {
-                        /* POV axis */
-                        joydev.dev_axes_map[j] = 8;
-                        found_axes++;
-                    }
-                    else
-                        joydev.dev_axes_map[j] = -1;
-                }
-
-                /* If no axes were configured but there are axes assume a 1-to-1 (wii controller) */
-                if (joydev.axis_count && !found_axes)
-                {
-                    int axes_limit = min(joydev.axis_count, 8); /* generic driver limit */
-
-                    ERR("Incoherent joystick data, advertised %d axes, detected 0. Assuming 1-to-1.\n",
-                        joydev.axis_count);
-                    for (j = 0; j < axes_limit; j++)
-                        joydev.dev_axes_map[j] = j;
-
-                    joydev.axis_count = axes_limit;
-                }
-            }
-
-        /* Find vendor_id and product_id in sysfs */
-        joydev.vendor_id  = 0;
-        joydev.product_id = 0;
-
-        read_sys_id_variable(i, "vendor", &joydev.vendor_id);
-        read_sys_id_variable(i, "product", &joydev.product_id);
-        read_sys_id_variable(i, "bustype", &joydev.bus_type);
-
-        if (joydev.vendor_id == 0 || joydev.product_id == 0)
-        {
-            joydev.guid_product = DInput_Wine_Joystick_GUID;
-        }
-        else
-        {
-            /* Concatenate product_id with vendor_id to mimic Windows behaviour */
-            joydev.guid_product       = dinput_pidvid_guid;
-            joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id);
-        }
-
-        close(fd);
-
-        if (!joystick_devices_count)
-            new_joydevs = HeapAlloc(GetProcessHeap(), 0, sizeof(struct JoyDev));
-        else
-            new_joydevs = HeapReAlloc(GetProcessHeap(), 0, joystick_devices,
-                                      (joystick_devices_count + 1) * sizeof(struct JoyDev));
-        if (!new_joydevs) continue;
-
-        TRACE("Found a joystick on %s: %s\n  with %d axes and %d buttons\n", joydev.device,
-              joydev.name, joydev.axis_count, joydev.button_count);
-
-        joystick_devices = new_joydevs;
-        joystick_devices[joystick_devices_count++] = joydev;
-    }
-
-    return joystick_devices_count;
-}
-
-static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
-{
-    DWORD dwSize = lpddi->dwSize;
-
-    TRACE("%d %p\n", dwSize, lpddi);
-    memset(lpddi, 0, dwSize);
-
-    /* Return joystick */
-    lpddi->dwSize = dwSize;
-    lpddi->guidInstance = DInput_Wine_Joystick_GUID;
-    lpddi->guidInstance.Data3 = id;
-    lpddi->guidProduct = joystick_devices[id].guid_product;
-    lpddi->dwDevType = get_device_type(version, joystick_devices[id].is_joystick);
-
-    /* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID */
-    if (joystick_devices[id].bus_type == BUS_USB &&
-        joystick_devices[id].vendor_id && joystick_devices[id].product_id)
-    {
-        lpddi->dwDevType |= DIDEVTYPE_HID;
-        lpddi->wUsagePage = 0x01; /* Desktop */
-        if (joystick_devices[id].is_joystick)
-            lpddi->wUsage = 0x04; /* Joystick */
-        else
-            lpddi->wUsage = 0x05; /* Game Pad */
-    }
-
-    MultiByteToWideChar(CP_ACP, 0, joystick_devices[id].name, -1, lpddi->tszInstanceName, MAX_PATH);
-    MultiByteToWideChar(CP_ACP, 0, joystick_devices[id].name, -1, lpddi->tszProductName, MAX_PATH);
-    lpddi->guidFFDriver = GUID_NULL;
-}
-
-static HRESULT joydev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
-{
-    int fd = -1;
-
-    if (id >= find_joystick_devices()) return E_FAIL;
-
-    if (dwFlags & DIEDFL_FORCEFEEDBACK) {
-        WARN("force feedback not supported\n");
-        return S_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 */
-        if ((fd = open(joystick_devices[id].device, O_RDONLY)) == -1)
-        {
-            WARN("open(%s, O_RDONLY) failed: %s\n", joystick_devices[id].device, strerror(errno));
-            return S_FALSE;
-        }
-        fill_joystick_dideviceinstanceW( lpddi, version, id );
-        close(fd);
-        TRACE("Enumerating the linux Joystick device: %s (%s)\n", joystick_devices[id].device, joystick_devices[id].name);
-        return S_OK;
-    }
-
-    return S_FALSE;
-}
-
-static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, JoystickImpl **out, unsigned short index )
-{
-    DWORD i;
-    JoystickImpl* newDevice;
-    HRESULT hr;
-    LPDIDATAFORMAT df = NULL;
-    int idx = 0;
-    DIDEVICEINSTANCEW ddi;
-
-    TRACE( "%s %p %p %hu\n", debugstr_guid( rguid ), dinput, out, index );
-
-    if (FAILED(hr = direct_input_device_alloc( sizeof(JoystickImpl), &JoystickWvt, rguid, dinput, (void **)&newDevice )))
-        return hr;
-    df = newDevice->generic.base.data_format.wine_df;
-    newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");
-
-    newDevice->joydev = &joystick_devices[index];
-    newDevice->joyfd = -1;
-    newDevice->generic.guidInstance = DInput_Wine_Joystick_GUID;
-    newDevice->generic.guidInstance.Data3 = index;
-    newDevice->generic.guidProduct = DInput_Wine_Joystick_GUID;
-    newDevice->generic.joy_polldev = joy_polldev;
-    newDevice->generic.name        = newDevice->joydev->name;
-    newDevice->generic.device_axis_count = newDevice->joydev->axis_count;
-    newDevice->generic.devcaps.dwButtons = newDevice->joydev->button_count;
-
-    if (newDevice->generic.devcaps.dwButtons > 128)
-    {
-        WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->generic.devcaps.dwButtons);
-        newDevice->generic.devcaps.dwButtons = 128;
-    }
-
-    /* setup_dinput_options may change these */
-    newDevice->generic.deadzone = 0;
-
-    /* do any user specified configuration */
-    hr = setup_dinput_options(&newDevice->generic, newDevice->joydev->dev_axes_map);
-    if (hr != DI_OK)
-        goto FAILED1;
-
-    /* Create copy of default data format */
-    memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
-
-    df->dwNumObjs = newDevice->generic.devcaps.dwAxes + newDevice->generic.devcaps.dwPOVs + newDevice->generic.devcaps.dwButtons;
-    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED;
-
-    for (i = 0; i < newDevice->generic.device_axis_count; i++)
-    {
-        int wine_obj = newDevice->generic.axis_map[i];
-
-        if (wine_obj < 0) continue;
-
-        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
-        if (wine_obj < 8)
-            df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
-        else
-        {
-            df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj - 8) | DIDFT_POV;
-            i++; /* POV takes 2 axes */
-        }
-    }
-    for (i = 0; i < newDevice->generic.devcaps.dwButtons; i++)
-    {
-        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize);
-        df->rgodf[idx  ].pguid = &GUID_Button;
-        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
-    }
-
-    /* initialize default properties */
-    for (i = 0; i < c_dfDIJoystick2.dwNumObjs; i++) {
-        newDevice->generic.props[i].lDevMin = -32767;
-        newDevice->generic.props[i].lDevMax = +32767;
-        newDevice->generic.props[i].lMin = 0;
-        newDevice->generic.props[i].lMax = 0xffff;
-        newDevice->generic.props[i].lDeadZone = newDevice->generic.deadzone; /* % * 1000 */
-        newDevice->generic.props[i].lSaturation = 0;
-    }
-
-    newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
-    newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
-
-    ddi.dwSize = sizeof(ddi);
-    fill_joystick_dideviceinstanceW(&ddi, newDevice->generic.base.dinput->dwVersion, index);
-    newDevice->generic.devcaps.dwDevType = ddi.dwDevType;
-
-    newDevice->generic.devcaps.dwFFSamplePeriod = 0;
-    newDevice->generic.devcaps.dwFFMinTimeResolution = 0;
-    newDevice->generic.devcaps.dwFirmwareRevision = 0;
-    newDevice->generic.devcaps.dwHardwareRevision = 0;
-    newDevice->generic.devcaps.dwFFDriverVersion = 0;
-
-    if (TRACE_ON(dinput)) {
-        _dump_DIDATAFORMAT(newDevice->generic.base.data_format.wine_df);
-       for (i = 0; i < (newDevice->generic.device_axis_count); i++)
-           TRACE("axis_map[%d] = %d\n", i, newDevice->generic.axis_map[i]);
-        _dump_DIDEVCAPS(&newDevice->generic.devcaps);
-    }
-
-    *out = newDevice;
-    return DI_OK;
-
-FAILED:
-    hr = DIERR_OUTOFMEMORY;
-FAILED1:
-    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
-    HeapFree(GetProcessHeap(), 0, df);
-    release_DataFormat(&newDevice->generic.base.data_format);
-    HeapFree(GetProcessHeap(),0,newDevice->generic.axis_map);
-    HeapFree(GetProcessHeap(),0,newDevice);
-    return hr;
-}
-
-/******************************************************************************
-  *     get_joystick_index : Get the joystick index from a given GUID
-  */
-static unsigned short get_joystick_index(REFGUID guid)
-{
-    GUID wine_joystick = DInput_Wine_Joystick_GUID;
-    GUID dev_guid = *guid;
-    INT i;
-
-    wine_joystick.Data3 = 0;
-    dev_guid.Data3 = 0;
-
-    /* for the standard joystick GUID use index 0 */
-    if(IsEqualGUID(&GUID_Joystick,guid)) return 0;
-
-    /* for the wine joystick GUIDs use the index stored in Data3 */
-    if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3;
-
-    for(i = 0; i < joystick_devices_count; i++)
-        if(IsEqualGUID(&joystick_devices[i].guid_product, guid)) return i;
-
-    return MAX_JOYSTICKS;
-}
-
-static HRESULT joydev_create_device( IDirectInputImpl *dinput, REFGUID rguid, IDirectInputDevice8W **out )
-{
-    unsigned short index;
-
-    TRACE( "%p %s %p\n", dinput, debugstr_guid( rguid ), out );
-    find_joystick_devices();
-    *out = NULL;
-
-    if ((index = get_joystick_index(rguid)) < MAX_JOYSTICKS &&
-        joystick_devices_count && index < joystick_devices_count)
-    {
-        JoystickImpl *This;
-        HRESULT hr;
-
-        if (FAILED(hr = alloc_device( rguid, dinput, &This, index ))) return hr;
-
-        TRACE( "Created a Joystick device (%p)\n", This );
-
-        *out = &This->generic.base.IDirectInputDevice8W_iface;
-        return hr;
-    }
-
-    return DIERR_DEVICENOTREG;
-}
-
-#undef MAX_JOYSTICKS
-
-const struct dinput_device joystick_linux_device = {
-  "Wine Linux joystick driver",
-  joydev_enum_device,
-  joydev_create_device
-};
-
-/******************************************************************************
-  *     Acquire : gets exclusive control of the joystick
-  */
-static HRESULT WINAPI JoystickLinuxWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-    HRESULT res;
-
-    TRACE("(%p)\n",This);
-
-    res = IDirectInputDevice2WImpl_Acquire(iface);
-    if (res != DI_OK)
-        return res;
-
-    /* open the joystick device */
-    if (This->joyfd==-1) {
-        TRACE("opening joystick device %s\n", This->joydev->device);
-
-        This->joyfd = open(This->joydev->device, O_RDONLY);
-        if (This->joyfd==-1) {
-            ERR("open(%s) failed: %s\n", This->joydev->device, strerror(errno));
-            IDirectInputDevice2WImpl_Unacquire(iface);
-            return DIERR_NOTFOUND;
-        }
-    }
-
-    return DI_OK;
-}
-
-/******************************************************************************
-  *     GetProperty : get input device properties
-  */
-static HRESULT WINAPI JoystickLinuxWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph);
-    _dump_DIPROPHEADER(pdiph);
-
-    if (!IS_DIPROP(rguid)) return DI_OK;
-
-    switch (LOWORD(rguid)) {
-
-        case (DWORD_PTR) DIPROP_VIDPID:
-        {
-            LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
-            if (!This->joydev->product_id || !This->joydev->vendor_id)
-                return DIERR_UNSUPPORTED;
-            pd->dwData = MAKELONG(This->joydev->vendor_id, This->joydev->product_id);
-            TRACE("DIPROP_VIDPID(%08x)\n", pd->dwData);
-            break;
-        }
-        case (DWORD_PTR) DIPROP_JOYSTICKID:
-        {
-            LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
-            pd->dwData = get_joystick_index(&This->generic.base.guid);
-            TRACE("DIPROP_JOYSTICKID(%d)\n", pd->dwData);
-            break;
-        }
-
-        case (DWORD_PTR) DIPROP_GUIDANDPATH:
-        {
-            static const WCHAR formatW[] = {'\\','\\','?','\\','h','i','d','#','v','i','d','_','%','0','4','x','&',
-                                            'p','i','d','_','%','0','4','x','&','%','s','_','%','h','u',0};
-            static const WCHAR miW[] = {'m','i',0};
-            static const WCHAR igW[] = {'i','g',0};
-
-            BOOL is_gamepad;
-            LPDIPROPGUIDANDPATH pd = (LPDIPROPGUIDANDPATH)pdiph;
-            WORD vid = This->joydev->vendor_id;
-            WORD pid = This->joydev->product_id;
-
-            if (!pid || !vid)
-                return DIERR_UNSUPPORTED;
-
-            is_gamepad = is_xinput_device(&This->generic.devcaps, vid, pid);
-            pd->guidClass = GUID_DEVCLASS_HIDCLASS;
-            sprintfW(pd->wszPath, formatW, vid, pid, is_gamepad ? igW : miW, get_joystick_index(&This->generic.base.guid));
-
-            TRACE("DIPROP_GUIDANDPATH(%s, %s): returning fake path\n", debugstr_guid(&pd->guidClass), debugstr_w(pd->wszPath));
-            break;
-        }
-
-    default:
-        return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph);
-    }
-
-    return DI_OK;
-}
-
-/******************************************************************************
-  *     GetDeviceInfo : get information about a device's identity
-  */
-static HRESULT WINAPI JoystickLinuxWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW ddi)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(%p) %p\n", This, ddi);
-
-    if (ddi == NULL) return E_POINTER;
-    if ((ddi->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) &&
-        (ddi->dwSize != sizeof(DIDEVICEINSTANCEW)))
-        return DIERR_INVALIDPARAM;
-
-    fill_joystick_dideviceinstanceW( ddi, This->generic.base.dinput->dwVersion,
-                                     get_joystick_index(&This->generic.base.guid) );
-
-    ddi->guidInstance = This->generic.base.guid;
-
-    return DI_OK;
-}
-
-/******************************************************************************
-  *     Unacquire : frees the joystick
-  */
-static HRESULT WINAPI JoystickLinuxWImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-    HRESULT res;
-
-    TRACE("(%p)\n",This);
-
-    res = IDirectInputDevice2WImpl_Unacquire(iface);
-
-    if (res != DI_OK)
-        return res;
-
-    if (This->joyfd!=-1) {
-        TRACE("closing joystick device\n");
-        close(This->joyfd);
-        This->joyfd = -1;
-        return DI_OK;
-    }
-
-    return DI_NOEFFECT;
-}
-
-static void joy_polldev( IDirectInputDevice8W *iface )
-{
-    struct pollfd plfd;
-    struct js_event jse;
-    JoystickImpl *This = impl_from_IDirectInputDevice8W( iface );
-
-    TRACE("(%p)\n", This);
-
-    if (This->joyfd==-1) {
-        WARN("no device\n");
-        return;
-    }
-    while (1)
-    {
-        LONG value;
-        int inst_id = -1;
-
-	plfd.fd = This->joyfd;
-	plfd.events = POLLIN;
-	if (poll(&plfd,1,0) != 1)
-	    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)
-        {
-            if (jse.number >= This->generic.devcaps.dwButtons) return;
-
-            inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON;
-            This->generic.js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00;
-        }
-        else if (jse.type & JS_EVENT_AXIS)
-        {
-            int number = This->generic.axis_map[jse.number];	/* wine format object index */
-
-            if (number < 0) return;
-            inst_id = number < 8 ?  DIDFT_MAKEINSTANCE(number) | DIDFT_ABSAXIS :
-                                    DIDFT_MAKEINSTANCE(number - 8) | DIDFT_POV;
-            value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], jse.value);
-
-            TRACE("changing axis %d => %d\n", jse.number, number);
-            switch (number)
-            {
-                case 0: This->generic.js.lX  = value; break;
-                case 1: This->generic.js.lY  = value; break;
-                case 2: This->generic.js.lZ  = value; break;
-                case 3: This->generic.js.lRx = value; break;
-                case 4: This->generic.js.lRy = value; break;
-                case 5: This->generic.js.lRz = value; break;
-                case 6: This->generic.js.rglSlider[0] = value; break;
-                case 7: This->generic.js.rglSlider[1] = value; break;
-                case 8: case 9: case 10: case 11:
-                {
-                    int idx = number - 8;
-
-                    if (jse.number % 2)
-                        This->povs[idx].y = jse.value;
-                    else
-                        This->povs[idx].x = jse.value;
-
-                    This->generic.js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]);
-                    break;
-                }
-                default:
-                    WARN("axis %d not supported\n", number);
-            }
-        }
-        if (inst_id >= 0)
-        {
-            queue_event(iface, inst_id, value, GetCurrentTime(), This->generic.base.dinput->evsequence++);
-            if (This->generic.base.hEvent) SetEvent( This->generic.base.hEvent );
-        }
-    }
-}
-
-static const IDirectInputDevice8WVtbl JoystickWvt =
-{
-    IDirectInputDevice2WImpl_QueryInterface,
-    IDirectInputDevice2WImpl_AddRef,
-    JoystickWGenericImpl_Release,
-    JoystickWGenericImpl_GetCapabilities,
-    IDirectInputDevice2WImpl_EnumObjects,
-    JoystickLinuxWImpl_GetProperty,
-    JoystickWGenericImpl_SetProperty,
-    JoystickLinuxWImpl_Acquire,
-    JoystickLinuxWImpl_Unacquire,
-    JoystickWGenericImpl_GetDeviceState,
-    IDirectInputDevice2WImpl_GetDeviceData,
-    IDirectInputDevice2WImpl_SetDataFormat,
-    IDirectInputDevice2WImpl_SetEventNotification,
-    IDirectInputDevice2WImpl_SetCooperativeLevel,
-    JoystickWGenericImpl_GetObjectInfo,
-    JoystickLinuxWImpl_GetDeviceInfo,
-    IDirectInputDevice2WImpl_RunControlPanel,
-    IDirectInputDevice2WImpl_Initialize,
-    IDirectInputDevice2WImpl_CreateEffect,
-    IDirectInputDevice2WImpl_EnumEffects,
-    IDirectInputDevice2WImpl_GetEffectInfo,
-    IDirectInputDevice2WImpl_GetForceFeedbackState,
-    IDirectInputDevice2WImpl_SendForceFeedbackCommand,
-    IDirectInputDevice2WImpl_EnumCreatedEffectObjects,
-    IDirectInputDevice2WImpl_Escape,
-    JoystickWGenericImpl_Poll,
-    IDirectInputDevice2WImpl_SendDeviceData,
-    IDirectInputDevice7WImpl_EnumEffectsInFile,
-    IDirectInputDevice7WImpl_WriteEffectToFile,
-    JoystickWGenericImpl_BuildActionMap,
-    JoystickWGenericImpl_SetActionMap,
-    IDirectInputDevice8WImpl_GetImageInfo
-};
-
-#else  /* HAVE_LINUX_22_JOYSTICK_API */
-
-const struct dinput_device joystick_linux_device = {
-  "Wine Linux joystick driver",
-  NULL,
-  NULL,
-};
-
-#endif  /* HAVE_LINUX_22_JOYSTICK_API */
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
deleted file mode 100644
index c7f4cc486fd..00000000000
--- a/dlls/dinput/joystick_linuxinput.c
+++ /dev/null
@@ -1,1276 +0,0 @@
-/*		DirectInput Joystick device
- *
- * Copyright 1998,2000 Marcus Meissner
- * Copyright 1998,1999 Lionel Ulmer
- * Copyright 2000-2001 TransGaming Technologies Inc.
- * Copyright 2005 Daniel Remenak
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-#include <fcntl.h>
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#include <errno.h>
-#ifdef HAVE_LINUX_INPUT_H
-# include <linux/input.h>
-# undef SW_MAX
-# if defined(EVIOCGBIT) && defined(EV_ABS) && defined(BTN_PINKIE)
-#  define HAS_PROPER_HEADER
-# endif
-#endif
-#ifdef HAVE_SYS_POLL_H
-# include <sys/poll.h>
-#endif
-
-#include "wine/debug.h"
-#include "wine/unicode.h"
-#include "wine/list.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "winreg.h"
-#include "devguid.h"
-#include "dinput.h"
-
-#include "dinput_private.h"
-#include "device_private.h"
-#include "joystick_private.h"
-
-#ifdef HAS_PROPER_HEADER
-
-WINE_DEFAULT_DEBUG_CHANNEL(dinput);
-
-#define EVDEVPREFIX "/dev/input/event"
-#define EVDEVDRIVER " (event)"
-
-/* Wine joystick driver object instances */
-#define WINE_JOYSTICK_MAX_AXES    8
-#define WINE_JOYSTICK_MAX_POVS    4
-#define WINE_JOYSTICK_MAX_BUTTONS 128
-
-struct wine_input_absinfo {
-    LONG value;
-    LONG minimum;
-    LONG maximum;
-    LONG fuzz;
-    LONG flat;
-};
-
-/* implemented in effect_linuxinput.c */
-HRESULT linuxinput_create_effect(int* fd, REFGUID rguid, struct list *parent_list_entry, LPDIRECTINPUTEFFECT* peff);
-HRESULT linuxinput_get_info_A(int fd, REFGUID rguid, LPDIEFFECTINFOA info);
-HRESULT linuxinput_get_info_W(int fd, REFGUID rguid, LPDIEFFECTINFOW info);
-
-static HRESULT WINAPI JoystickWImpl_SendForceFeedbackCommand(LPDIRECTINPUTDEVICE8W iface, DWORD dwFlags);
-
-typedef struct JoystickImpl JoystickImpl;
-static const IDirectInputDevice8WVtbl JoystickWvt;
-
-struct JoyDev {
-	char *device;
-	char *name;
-	GUID guid;
-	GUID guid_product;
-
-        BOOL has_ff, is_joystick;
-        int num_effects;
-
-	/* data returned by EVIOCGBIT for caps, EV_ABS, EV_KEY, and EV_FF */
-	BYTE				evbits[(EV_MAX+7)/8];
-	BYTE				absbits[(ABS_MAX+7)/8];
-	BYTE				keybits[(KEY_MAX+7)/8];
-	BYTE				ffbits[(FF_MAX+7)/8];	
-
-	/* data returned by the EVIOCGABS() ioctl */
-        struct wine_input_absinfo       axes[ABS_MAX];
-
-        WORD vendor_id, product_id, bus_type;
-};
-
-struct JoystickImpl
-{
-        struct JoystickGenericImpl      generic;
-        struct JoyDev                  *joydev;
-
-	/* joystick private */
-	int				joyfd;
-
-	int                             dev_axes_to_di[ABS_MAX];
-        POINTL                          povs[4];
-
-	/* LUT for KEY_ to offset in rgbButtons */
-	BYTE				buttons[KEY_MAX];
-
-	/* Force feedback variables */
-        struct list                     ff_effects;
-	int				ff_state;
-	int				ff_autocenter;
-	int				ff_gain;
-};
-
-static inline JoystickImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface)
-{
-    return CONTAINING_RECORD(CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8W_iface),
-           JoystickGenericImpl, base), JoystickImpl, generic);
-}
-
-static void fake_current_js_state(JoystickImpl *ji);
-static void find_joydevs(void);
-static void joy_polldev( IDirectInputDevice8W *iface );
-
-/* This GUID is slightly different from the linux joystick one. Take note. */
-static const GUID DInput_Wine_Joystick_Base_GUID = { /* 9e573eda-7734-11d2-8d4a-23903fb6bdf7 */
-  0x9e573eda,
-  0x7734,
-  0x11d2,
-  {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
-};
-
-#define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7)))
-
-#define MAX_JOYDEV 64
-
-static int have_joydevs = -1;
-static struct JoyDev *joydevs = NULL;
-
-static void find_joydevs(void)
-{
-    int i;
-
-    if (InterlockedCompareExchange(&have_joydevs, 0, -1) != -1)
-        /* Someone beat us to it */
-        return;
-
-    for (i = 0; i < MAX_JOYDEV; i++)
-    {
-        char buf[MAX_PATH];
-        struct JoyDev joydev = {0};
-        int fd;
-        BOOL no_ff_check = FALSE;
-        int j;
-        struct JoyDev *new_joydevs;
-        struct input_id device_id = {0};
-
-        snprintf(buf, sizeof(buf), EVDEVPREFIX"%d", i);
-
-        if ((fd = open(buf, O_RDWR)) == -1)
-        {
-            fd = open(buf, O_RDONLY);
-            no_ff_check = TRUE;
-        }
-
-        if (fd == -1)
-            continue;
-
-        if (ioctl(fd, EVIOCGBIT(0, sizeof(joydev.evbits)), joydev.evbits) == -1)
-        {
-            WARN("ioctl(EVIOCGBIT, 0) failed: %d %s\n", errno, strerror(errno));
-            close(fd);
-            continue;
-        }
-        if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(joydev.absbits)), joydev.absbits) == -1)
-        {
-            WARN("ioctl(EVIOCGBIT, EV_ABS) failed: %d %s\n", errno, strerror(errno));
-            close(fd);
-            continue;
-        }
-        if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(joydev.keybits)), joydev.keybits) == -1)
-        {
-            WARN("ioctl(EVIOCGBIT, EV_KEY) failed: %d %s\n", errno, strerror(errno));
-            close(fd);
-            continue;
-        }
-
-        /* A true joystick has at least axis X and Y, and at least 1
-         * button. copied from linux/drivers/input/joydev.c */
-        if (((!test_bit(joydev.absbits, ABS_X) || !test_bit(joydev.absbits, ABS_Y)) &&
-             !test_bit(joydev.absbits, ABS_WHEEL) &&
-             !test_bit(joydev.absbits, ABS_GAS) &&
-             !test_bit(joydev.absbits, ABS_BRAKE)) ||
-            !(test_bit(joydev.keybits, BTN_TRIGGER) ||
-              test_bit(joydev.keybits, BTN_A) ||
-              test_bit(joydev.keybits, BTN_1) ||
-              test_bit(joydev.keybits, BTN_BASE) ||
-              test_bit(joydev.keybits, BTN_GEAR_UP) ||
-              test_bit(joydev.keybits, BTN_GEAR_DOWN)))
-        {
-            close(fd);
-            continue;
-        }
-
-        /* in lieu of properly reporting HID usage, detect presence of
-         * "joystick buttons" and report those devices as joysticks instead of
-         * gamepads */
-        joydev.is_joystick =
-            test_bit(joydev.keybits, BTN_TRIGGER) ||
-            test_bit(joydev.keybits, BTN_THUMB) ||
-            test_bit(joydev.keybits, BTN_THUMB2) ||
-            test_bit(joydev.keybits, BTN_TOP) ||
-            test_bit(joydev.keybits, BTN_TOP2) ||
-            test_bit(joydev.keybits, BTN_PINKIE) ||
-            test_bit(joydev.keybits, BTN_BASE) ||
-            test_bit(joydev.keybits, BTN_BASE2) ||
-            test_bit(joydev.keybits, BTN_BASE3) ||
-            test_bit(joydev.keybits, BTN_BASE4) ||
-            test_bit(joydev.keybits, BTN_BASE5) ||
-            test_bit(joydev.keybits, BTN_BASE6) ||
-            test_bit(joydev.keybits, BTN_GEAR_UP) ||
-            test_bit(joydev.keybits, BTN_GEAR_DOWN) ||
-            test_bit(joydev.keybits, BTN_DEAD);
-
-        if (!(joydev.device = HeapAlloc(GetProcessHeap(), 0, strlen(buf) + 1)))
-        {
-            close(fd);
-            continue;
-        }
-        strcpy(joydev.device, buf);
-
-        buf[MAX_PATH - 1] = 0;
-        if (ioctl(fd, EVIOCGNAME(MAX_PATH - 1), buf) != -1 &&
-            (joydev.name = HeapAlloc(GetProcessHeap(), 0, strlen(buf) + strlen(EVDEVDRIVER) + 1)))
-        {
-            strcpy(joydev.name, buf);
-            /* Append driver name */
-            strcat(joydev.name, EVDEVDRIVER);
-        }
-        else
-            joydev.name = joydev.device;
-
-        if (device_disabled_registry(joydev.name)) {
-            close(fd);
-            HeapFree(GetProcessHeap(), 0, joydev.name);
-            if (joydev.name != joydev.device)
-                HeapFree(GetProcessHeap(), 0, joydev.device);
-            continue;
-        }
-
-        joydev.guid = DInput_Wine_Joystick_Base_GUID;
-        joydev.guid.Data3 += have_joydevs;
-
-        TRACE("Found a joystick on %s: %s (%s)\n",
-            joydev.device, joydev.name, 
-            debugstr_guid(&joydev.guid)
-            );
-
-#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
-        if (!no_ff_check &&
-            test_bit(joydev.evbits, EV_FF) &&
-            ioctl(fd, EVIOCGBIT(EV_FF, sizeof(joydev.ffbits)), joydev.ffbits) != -1 &&
-            ioctl(fd, EVIOCGEFFECTS, &joydev.num_effects) != -1 &&
-            joydev.num_effects > 0)
-        {
-	    TRACE(" ... with force feedback\n");
-            joydev.has_ff = TRUE;
-        }
-#endif
-
-        for (j = 0; j < ABS_MAX;j ++)
-        {
-            if (!test_bit(joydev.absbits, j)) continue;
-            if (ioctl(fd, EVIOCGABS(j), &(joydev.axes[j])) != -1)
-            {
-	      TRACE(" ... with axis %d: cur=%d, min=%d, max=%d, fuzz=%d, flat=%d\n",
-		  j,
-		  joydev.axes[j].value,
-		  joydev.axes[j].minimum,
-		  joydev.axes[j].maximum,
-		  joydev.axes[j].fuzz,
-		  joydev.axes[j].flat
-		  );
-	    }
-	}
-
-        if (ioctl(fd, EVIOCGID, &device_id) == -1)
-        {
-            WARN("ioctl(EVIOCGID) failed: %d %s\n", errno, strerror(errno));
-            joydev.guid_product = DInput_Wine_Joystick_Base_GUID;
-        }
-        else
-        {
-            joydev.vendor_id = device_id.vendor;
-            joydev.product_id = device_id.product;
-            joydev.bus_type = device_id.bustype;
-
-            /* Concatenate product_id with vendor_id to mimic Windows behaviour */
-            joydev.guid_product       = dinput_pidvid_guid;
-            joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id);
-        }
-
-        if (!have_joydevs)
-            new_joydevs = HeapAlloc(GetProcessHeap(), 0, sizeof(struct JoyDev));
-        else
-            new_joydevs = HeapReAlloc(GetProcessHeap(), 0, joydevs, (1 + have_joydevs) * sizeof(struct JoyDev));
-
-        if (!new_joydevs)
-        {
-            close(fd);
-            continue;
-        }
-        joydevs = new_joydevs;
-        joydevs[have_joydevs] = joydev;
-        have_joydevs++;
-
-        close(fd);
-    }
-}
-
-static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
-{
-    DWORD dwSize = lpddi->dwSize;
-
-    TRACE("%d %p\n", dwSize, lpddi);
-    memset(lpddi, 0, dwSize);
-
-    lpddi->dwSize       = dwSize;
-    lpddi->guidInstance = joydevs[id].guid;
-    lpddi->guidProduct  = joydevs[id].guid_product;
-    lpddi->guidFFDriver = GUID_NULL;
-    lpddi->dwDevType = get_device_type(version, joydevs[id].is_joystick);
-
-    /* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID */
-    if (joydevs[id].bus_type == BUS_USB &&
-        joydevs[id].vendor_id && joydevs[id].product_id)
-    {
-        lpddi->dwDevType |= DIDEVTYPE_HID;
-        lpddi->wUsagePage = 0x01; /* Desktop */
-        if (joydevs[id].is_joystick)
-            lpddi->wUsage = 0x04; /* Joystick */
-        else
-            lpddi->wUsage = 0x05; /* Game Pad */
-    }
-
-    MultiByteToWideChar(CP_ACP, 0, joydevs[id].name, -1, lpddi->tszInstanceName, MAX_PATH);
-    MultiByteToWideChar(CP_ACP, 0, joydevs[id].name, -1, lpddi->tszProductName, MAX_PATH);
-}
-
-static HRESULT joydev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
-{
-  find_joydevs();
-
-  if (id >= have_joydevs) {
-    return E_FAIL;
-  }
-
-  if (!((dwDevType == 0) ||
-        ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) ||
-        (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))))
-    return S_FALSE;
-
-#ifndef HAVE_STRUCT_FF_EFFECT_DIRECTION
-  if (dwFlags & DIEDFL_FORCEFEEDBACK)
-    return S_FALSE;
-#endif
-
-  if (!(dwFlags & DIEDFL_FORCEFEEDBACK) || joydevs[id].has_ff) {
-    fill_joystick_dideviceinstanceW(lpddi, version, id);
-    return S_OK;
-  }
-  return S_FALSE;
-}
-
-static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, JoystickImpl **out, unsigned short index )
-{
-    JoystickImpl* newDevice;
-    LPDIDATAFORMAT df = NULL;
-    int i, idx = 0;
-    int default_axis_map[WINE_JOYSTICK_MAX_AXES + WINE_JOYSTICK_MAX_POVS*2];
-    DIDEVICEINSTANCEW ddi;
-    HRESULT hr;
-
-    if (FAILED(hr = direct_input_device_alloc( sizeof(JoystickImpl), &JoystickWvt, rguid, dinput, (void **)&newDevice )))
-        return hr;
-    df = newDevice->generic.base.data_format.wine_df;
-    newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->base.crit");
-
-    newDevice->generic.joy_polldev = joy_polldev;
-    newDevice->joyfd       = -1;
-    newDevice->joydev      = &joydevs[index];
-    newDevice->generic.name        = newDevice->joydev->name;
-    list_init(&newDevice->ff_effects);
-#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
-    newDevice->ff_state    = FF_STATUS_STOPPED;
-#endif
-    /* There is no way in linux to query force feedback autocenter status.
-       Instead, track it with ff_autocenter, and assume it's initially
-       enabled. */
-    newDevice->ff_autocenter = 1;
-    newDevice->ff_gain = 0xFFFF;
-
-    /* Count number of available axes - supported Axis & POVs */
-    for (i = 0; i < ABS_MAX; i++)
-    {
-        if (idx < WINE_JOYSTICK_MAX_AXES &&
-            i < ABS_HAT0X &&
-            test_bit(newDevice->joydev->absbits, i))
-        {
-            newDevice->generic.device_axis_count++;
-            newDevice->dev_axes_to_di[i] = idx;
-            newDevice->generic.props[idx].lDevMin = newDevice->joydev->axes[i].minimum;
-            newDevice->generic.props[idx].lDevMax = newDevice->joydev->axes[i].maximum;
-            if (i >= 8 && i <= 10) /* If it's a wheel axis... */
-                default_axis_map[idx] = i - 8; /* ... remap to X/Y/Z */
-            else
-                default_axis_map[idx] = i;
-            idx++;
-        }
-        else
-            newDevice->dev_axes_to_di[i] = -1;
-    }
-
-    for (i = 0; i < WINE_JOYSTICK_MAX_POVS; i++)
-    {
-        if (test_bit(newDevice->joydev->absbits, ABS_HAT0X + i * 2) &&
-            test_bit(newDevice->joydev->absbits, ABS_HAT0Y + i * 2))
-        {
-            newDevice->generic.device_axis_count += 2;
-            newDevice->generic.props[idx  ].lDevMin = newDevice->joydev->axes[ABS_HAT0X + i * 2].minimum;
-            newDevice->generic.props[idx  ].lDevMax = newDevice->joydev->axes[ABS_HAT0X + i * 2].maximum;
-            newDevice->dev_axes_to_di[ABS_HAT0X + i * 2] = idx;
-            newDevice->generic.props[idx+1].lDevMin = newDevice->joydev->axes[ABS_HAT0Y + i * 2].minimum;
-            newDevice->generic.props[idx+1].lDevMax = newDevice->joydev->axes[ABS_HAT0Y + i * 2].maximum;
-            newDevice->dev_axes_to_di[ABS_HAT0Y + i * 2] = idx + 1;
-
-            default_axis_map[idx] = default_axis_map[idx + 1] = WINE_JOYSTICK_MAX_AXES + i;
-            idx += 2;
-        }
-        else
-            newDevice->dev_axes_to_di[ABS_HAT0X + i * 2] = newDevice->dev_axes_to_di[ABS_HAT0Y + i * 2] = -1;
-    }
-
-    /* do any user specified configuration */
-    if (setup_dinput_options(&newDevice->generic, default_axis_map) != DI_OK) goto failed;
-
-    /* Create copy of default data format */
-    memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
-    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed;
-
-
-    /* Construct internal data format */
-
-    /* Supported Axis & POVs */
-    for (i = 0, idx = 0; i < newDevice->generic.device_axis_count; i++)
-    {
-        int wine_obj = newDevice->generic.axis_map[i];
-
-        if (wine_obj < 0) continue;
-
-        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
-        if (wine_obj < 8)
-            df->rgodf[idx].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
-        else
-        {
-            df->rgodf[idx].dwType = DIDFT_MAKEINSTANCE(wine_obj - 8) | DIDFT_POV;
-            i++; /* POV takes 2 axes */
-        }
-
-        newDevice->generic.props[idx].lMin        = 0;
-        newDevice->generic.props[idx].lMax        = 0xffff;
-        newDevice->generic.props[idx].lSaturation = 0;
-        newDevice->generic.props[idx].lDeadZone   = newDevice->generic.deadzone;
-
-        /* Linux supports force-feedback on X & Y axes only */
-        if (newDevice->joydev->has_ff && (i == 0 || i == 1))
-            df->rgodf[idx].dwFlags |= DIDOI_FFACTUATOR;
-
-        idx++;
-    }
-
-    /* Buttons can be anywhere, so check all */
-    for (i = 0; i < KEY_MAX && newDevice->generic.devcaps.dwButtons < WINE_JOYSTICK_MAX_BUTTONS; i++)
-    {
-        if (!test_bit(newDevice->joydev->keybits, i)) continue;
-
-        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[newDevice->generic.devcaps.dwButtons + 12], df->dwObjSize);
-        newDevice->buttons[i] = 0x80 | newDevice->generic.devcaps.dwButtons;
-        df->rgodf[idx  ].pguid = &GUID_Button;
-        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(newDevice->generic.devcaps.dwButtons++) | DIDFT_PSHBUTTON;
-    }
-    df->dwNumObjs = idx;
-
-    fake_current_js_state(newDevice);
-
-    /* Fill the caps */
-    newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
-    newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
-
-    ddi.dwSize = sizeof(ddi);
-    fill_joystick_dideviceinstanceW(&ddi, newDevice->generic.base.dinput->dwVersion, index);
-    newDevice->generic.devcaps.dwDevType = ddi.dwDevType;
-
-    if (newDevice->joydev->has_ff)
-        newDevice->generic.devcaps.dwFlags |= DIDC_FORCEFEEDBACK;
-
-    *out = newDevice;
-    return DI_OK;
-
-failed:
-    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
-    HeapFree(GetProcessHeap(), 0, df);
-    HeapFree(GetProcessHeap(), 0, newDevice->generic.axis_map);
-    HeapFree(GetProcessHeap(), 0, newDevice);
-    return DIERR_OUTOFMEMORY;
-}
-
-/******************************************************************************
-  *     get_joystick_index : Get the joystick index from a given GUID
-  */
-static unsigned short get_joystick_index(REFGUID guid)
-{
-    GUID wine_joystick = DInput_Wine_Joystick_Base_GUID;
-    GUID dev_guid = *guid;
-    INT i;
-
-    wine_joystick.Data3 = 0;
-    dev_guid.Data3 = 0;
-
-    /* for the standard joystick GUID use index 0 */
-    if(IsEqualGUID(&GUID_Joystick,guid)) return 0;
-
-    /* for the wine joystick GUIDs use the index stored in Data3 */
-    if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3 - DInput_Wine_Joystick_Base_GUID.Data3;
-
-    for(i = 0; i < have_joydevs; i++)
-        if(IsEqualGUID(&joydevs[i].guid_product, guid)) return i;
-
-    return MAX_JOYDEV;
-}
-
-static HRESULT joydev_create_device( IDirectInputImpl *dinput, REFGUID rguid, IDirectInputDevice8W **out )
-{
-    unsigned short index;
-
-    TRACE( "%p %s %p\n", dinput, debugstr_guid( rguid ), out );
-    find_joydevs();
-    *out = NULL;
-
-    if ((index = get_joystick_index(rguid)) < MAX_JOYDEV &&
-        have_joydevs && index < have_joydevs)
-    {
-        JoystickImpl *This;
-        HRESULT hr;
-
-        if (FAILED(hr = alloc_device( rguid, dinput, &This, index ))) return hr;
-
-        TRACE( "Created a Joystick device (%p)\n", This );
-
-        *out = &This->generic.base.IDirectInputDevice8W_iface;
-        return DI_OK;
-    }
-
-    return DIERR_DEVICENOTREG;
-}
-
-
-const struct dinput_device joystick_linuxinput_device = {
-  "Wine Linux-input joystick driver",
-  joydev_enum_device,
-  joydev_create_device
-};
-
-/******************************************************************************
-  *     Acquire : gets exclusive control of the joystick
-  */
-static HRESULT WINAPI JoystickWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-    HRESULT res;
-
-    TRACE("(this=%p)\n",This);
-
-    if ((res = IDirectInputDevice2WImpl_Acquire(iface)) != DI_OK)
-    {
-        WARN("Failed to acquire: %x\n", res);
-        return res;
-    }
-
-    if ((This->joyfd = open(This->joydev->device, O_RDWR)) == -1)
-    {
-        if ((This->joyfd = open(This->joydev->device, O_RDONLY)) == -1)
-        {
-            /* Couldn't open the device at all */
-            ERR("Failed to open device %s: %d %s\n", This->joydev->device, errno, strerror(errno));
-            IDirectInputDevice2WImpl_Unacquire(iface);
-            return DIERR_NOTFOUND;
-        }
-        else
-        {
-            /* Couldn't open in r/w but opened in read-only. */
-            WARN("Could not open %s in read-write mode.  Force feedback will be disabled.\n", This->joydev->device);
-        }
-    }
-    else
-    {
-        struct input_event event;
-
-        event.type = EV_FF;
-        event.code = FF_GAIN;
-        event.value = This->ff_gain;
-        if (write(This->joyfd, &event, sizeof(event)) == -1)
-            ERR("Failed to set gain (%i): %d %s\n", This->ff_gain, errno, strerror(errno));
-        if (!This->ff_autocenter)
-        {
-            /* Disable autocenter. */
-            event.code = FF_AUTOCENTER;
-            event.value = 0;
-            if (write(This->joyfd, &event, sizeof(event)) == -1)
-                ERR("Failed disabling autocenter: %d %s\n", errno, strerror(errno));
-        }
-    }
-
-    return DI_OK;
-}
-
-/******************************************************************************
-  *     Unacquire : frees the joystick
-  */
-static HRESULT WINAPI JoystickWImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-    HRESULT res;
-
-    TRACE("(this=%p)\n",This);
-    res = IDirectInputDevice2WImpl_Unacquire(iface);
-    if (res==DI_OK && This->joyfd!=-1) {
-      struct input_event event;
-
-      /* Stop and unload all effects */
-      JoystickWImpl_SendForceFeedbackCommand(iface, DISFFC_RESET);
-
-      /* Enable autocenter. */
-      event.type = EV_FF;
-      event.code = FF_AUTOCENTER;
-      /* TODO: Read autocenter strength before disabling it, and use it here
-       * instead of 0xFFFF (maximum strength).
-       */
-      event.value = 0xFFFF;
-      if (write(This->joyfd, &event, sizeof(event)) == -1)
-        ERR("Failed to set autocenter to %04x: %d %s\n", event.value, errno, strerror(errno));
-
-      close(This->joyfd);
-      This->joyfd = -1;
-    }
-    return res;
-}
-
-/* 
- * set the current state of the js device as it would be with the middle
- * values on the axes
- */
-#define CENTER_AXIS(a) \
-    (ji->dev_axes_to_di[a] == -1 ? 0 : joystick_map_axis( &ji->generic.props[ji->dev_axes_to_di[a]], \
-                                                          ji->joydev->axes[a].value ))
-static void fake_current_js_state(JoystickImpl *ji)
-{
-    int i;
-
-    /* center the axes */
-    ji->generic.js.lX           = CENTER_AXIS(ABS_X);
-    ji->generic.js.lY           = CENTER_AXIS(ABS_Y);
-    ji->generic.js.lZ           = CENTER_AXIS(ABS_Z);
-    ji->generic.js.lRx          = CENTER_AXIS(ABS_RX);
-    ji->generic.js.lRy          = CENTER_AXIS(ABS_RY);
-    ji->generic.js.lRz          = CENTER_AXIS(ABS_RZ);
-    ji->generic.js.rglSlider[0] = CENTER_AXIS(ABS_THROTTLE);
-    ji->generic.js.rglSlider[1] = CENTER_AXIS(ABS_RUDDER);
-
-    /* POV center is -1 */
-    for (i = 0; i < 4; i++)
-        ji->generic.js.rgdwPOV[i] = -1;
-}
-#undef CENTER_AXIS
-
-/* convert wine format offset to user format object index */
-static void joy_polldev( IDirectInputDevice8W *iface )
-{
-    struct pollfd plfd;
-    struct input_event ie;
-    JoystickImpl *This = impl_from_IDirectInputDevice8W( iface );
-
-    if (This->joyfd==-1)
-	return;
-
-    while (1)
-    {
-        LONG value = 0;
-        int inst_id = -1;
-
-	plfd.fd = This->joyfd;
-	plfd.events = POLLIN;
-
-	if (poll(&plfd,1,0) != 1)
-	    return;
-
-	/* we have one event, so we can read */
-	if (sizeof(ie)!=read(This->joyfd,&ie,sizeof(ie)))
-	    return;
-
-	TRACE("input_event: type %d, code %d, value %d\n",ie.type,ie.code,ie.value);
-	switch (ie.type) {
-	case EV_KEY:	/* button */
-        {
-            int btn = This->buttons[ie.code];
-
-            TRACE("(%p) %d -> %d\n", This, ie.code, btn);
-            if (btn & 0x80)
-            {
-                btn &= 0x7F;
-                inst_id = DIDFT_MAKEINSTANCE(btn) | DIDFT_PSHBUTTON;
-                This->generic.js.rgbButtons[btn] = value = ie.value ? 0x80 : 0x00;
-            }
-            break;
-        }
-	case EV_ABS:
-        {
-            int axis = This->dev_axes_to_di[ie.code];
-
-            /* User axis remapping */
-            if (axis < 0) break;
-            axis = This->generic.axis_map[axis];
-            if (axis < 0) break;
-
-            inst_id = axis < 8 ?  DIDFT_MAKEINSTANCE(axis) | DIDFT_ABSAXIS :
-                                  DIDFT_MAKEINSTANCE(axis - 8) | DIDFT_POV;
-            value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], ie.value);
-
-	    switch (axis) {
-            case 0: This->generic.js.lX  = value; break;
-            case 1: This->generic.js.lY  = value; break;
-            case 2: This->generic.js.lZ  = value; break;
-            case 3: This->generic.js.lRx = value; break;
-            case 4: This->generic.js.lRy = value; break;
-            case 5: This->generic.js.lRz = value; break;
-            case 6: This->generic.js.rglSlider[0] = value; break;
-            case 7: This->generic.js.rglSlider[1] = value; break;
-            case 8: case 9: case 10: case 11:
-            {
-                int idx = axis - 8;
-
-                if (ie.code % 2)
-                    This->povs[idx].y = ie.value;
-                else
-                    This->povs[idx].x = ie.value;
-
-                This->generic.js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]);
-                break;
-            }
-	    default:
-		FIXME("unhandled joystick axis event (code %d, value %d)\n",ie.code,ie.value);
-	    }
-	    break;
-        }
-#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
-	case EV_FF_STATUS:
-	    This->ff_state = ie.value;
-	    break;
-#endif
-#ifdef EV_SYN
-	case EV_SYN:
-	    /* there is nothing to do */
-	    break;
-#endif
-#ifdef EV_MSC
-        case EV_MSC:
-            /* Ignore */
-            break;
-#endif
-	default:
-	    TRACE("skipping event\n");
-	    break;
-	}
-        if (inst_id >= 0)
-        {
-            queue_event(iface, inst_id,
-                        value, GetCurrentTime(), This->generic.base.dinput->evsequence++);
-            if (This->generic.base.hEvent) SetEvent( This->generic.base.hEvent );
-        }
-    }
-}
-
-/******************************************************************************
-  *     SetProperty : change input device properties
-  */
-static HRESULT WINAPI JoystickWImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIPROPHEADER ph)
-{
-  JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-  if (!ph) {
-    WARN("invalid argument\n");
-    return DIERR_INVALIDPARAM;
-  }
-
-  TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
-  TRACE("ph.dwSize = %d, ph.dwHeaderSize =%d, ph.dwObj = %d, ph.dwHow= %d\n",
-        ph->dwSize, ph->dwHeaderSize, ph->dwObj, ph->dwHow);
-
-  if (IS_DIPROP(rguid)) {
-    switch (LOWORD(rguid)) {
-    case (DWORD_PTR)DIPROP_AUTOCENTER: {
-      LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
-
-      TRACE("autocenter(%d)\n", pd->dwData);
-      This->ff_autocenter = pd->dwData == DIPROPAUTOCENTER_ON;
-
-      break;
-    }
-    case (DWORD_PTR)DIPROP_FFGAIN: {
-      LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
-
-      TRACE("DIPROP_FFGAIN(%d)\n", pd->dwData);
-      This->ff_gain = MulDiv(pd->dwData, 0xFFFF, 10000);
-      if (This->generic.base.acquired) {
-        /* Update immediately. */
-        struct input_event event;
-
-        event.type = EV_FF;
-        event.code = FF_GAIN;
-        event.value = This->ff_gain;
-        if (write(This->joyfd, &event, sizeof(event)) == -1)
-          ERR("Failed to set gain (%i): %d %s\n", This->ff_gain, errno, strerror(errno));
-      }
-      break;
-    }
-    default:
-      return JoystickWGenericImpl_SetProperty(iface, rguid, ph);
-    }
-  }
-  return DI_OK;
-}
-
-/******************************************************************************
-  *     GetProperty : get input device properties
-  */
-static HRESULT WINAPI JoystickWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph);
-    _dump_DIPROPHEADER(pdiph);
-
-    if (!IS_DIPROP(rguid)) return DI_OK;
-
-    switch (LOWORD(rguid)) {
-    case (DWORD_PTR) DIPROP_AUTOCENTER:
-    {
-        LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
-        pd->dwData = This->ff_autocenter ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF;
-        TRACE("autocenter(%d)\n", pd->dwData);
-        break;
-    }
-    case (DWORD_PTR) DIPROP_FFGAIN:
-    {
-        LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
-        pd->dwData = MulDiv(This->ff_gain, 10000, 0xFFFF);
-        TRACE("DIPROP_FFGAIN(%d)\n", pd->dwData);
-        break;
-    }
-
-    case (DWORD_PTR) DIPROP_VIDPID:
-    {
-        LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
-        if (!This->joydev->product_id || !This->joydev->vendor_id)
-            return DIERR_UNSUPPORTED;
-        pd->dwData = MAKELONG(This->joydev->vendor_id, This->joydev->product_id);
-        TRACE("DIPROP_VIDPID(%08x)\n", pd->dwData);
-        break;
-    }
-
-    case (DWORD_PTR) DIPROP_JOYSTICKID:
-    {
-        LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
-        pd->dwData = get_joystick_index(&This->generic.base.guid);
-        TRACE("DIPROP_JOYSTICKID(%d)\n", pd->dwData);
-        break;
-    }
-
-    case (DWORD_PTR) DIPROP_GUIDANDPATH:
-    {
-        static const WCHAR formatW[] = {'\\','\\','?','\\','h','i','d','#','v','i','d','_','%','0','4','x','&',
-                                        'p','i','d','_','%','0','4','x','&','%','s','_','%','h','u',0};
-        static const WCHAR miW[] = {'m','i',0};
-        static const WCHAR igW[] = {'i','g',0};
-
-        BOOL is_gamepad;
-        LPDIPROPGUIDANDPATH pd = (LPDIPROPGUIDANDPATH)pdiph;
-        WORD vid = This->joydev->vendor_id;
-        WORD pid = This->joydev->product_id;
-
-        if (!pid || !vid)
-            return DIERR_UNSUPPORTED;
-
-        is_gamepad = is_xinput_device(&This->generic.devcaps, vid, pid);
-        pd->guidClass = GUID_DEVCLASS_HIDCLASS;
-        sprintfW(pd->wszPath, formatW, vid, pid, is_gamepad ? igW : miW, get_joystick_index(&This->generic.base.guid));
-
-        TRACE("DIPROP_GUIDANDPATH(%s, %s): returning fake path\n", debugstr_guid(&pd->guidClass), debugstr_w(pd->wszPath));
-        break;
-    }
-
-    default:
-        return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph);
-    }
-
-    return DI_OK;
-}
-
-/****************************************************************************** 
-  *	CreateEffect - Create a new FF effect with the specified params
-  */
-static HRESULT WINAPI JoystickWImpl_CreateEffect(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid,
-                                                 LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdef,
-                                                 LPUNKNOWN pUnkOuter)
-{
-#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
-    effect_list_item* new_effect = NULL;
-    HRESULT retval = DI_OK;
-#endif
-
-    JoystickImpl* This = impl_from_IDirectInputDevice8W(iface);
-    TRACE("(this=%p,%p,%p,%p,%p)\n", This, rguid, lpeff, ppdef, pUnkOuter);
-
-    *ppdef = NULL;
-    if (!This->joydev->has_ff)
-    {
-        TRACE("No force feedback support\n");
-        return DIERR_UNSUPPORTED;
-    }
-
-#ifndef HAVE_STRUCT_FF_EFFECT_DIRECTION
-    TRACE("not available (compiled w/o force feedback support)\n");
-    return DIERR_UNSUPPORTED;
-#else
-
-    if (!(new_effect = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_effect))))
-        return DIERR_OUTOFMEMORY;
-
-    retval = linuxinput_create_effect(&This->joyfd, rguid, &new_effect->entry, &new_effect->ref);
-    if (retval != DI_OK)
-    {
-        HeapFree(GetProcessHeap(), 0, new_effect);
-        return retval;
-    }
-
-    if (lpeff != NULL)
-    {
-        retval = IDirectInputEffect_SetParameters(new_effect->ref, lpeff,
-            DIEP_AXES | DIEP_DIRECTION | DIEP_DURATION | DIEP_ENVELOPE |
-            DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_STARTDELAY | DIEP_TRIGGERBUTTON |
-            DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS);
-
-        if (retval != DI_OK && retval != DI_DOWNLOADSKIPPED)
-        {
-            HeapFree(GetProcessHeap(), 0, new_effect);
-            return retval;
-        }
-    }
-
-    list_add_tail(&This->ff_effects, &new_effect->entry);
-    *ppdef = new_effect->ref;
-
-    if (pUnkOuter != NULL)
-	FIXME("Interface aggregation not implemented.\n");
-
-    return DI_OK;
-
-#endif /* HAVE_STRUCT_FF_EFFECT_DIRECTION */
-}
-
-/*******************************************************************************
- *	EnumEffects - Enumerate available FF effects
- */
-static HRESULT WINAPI JoystickWImpl_EnumEffects(LPDIRECTINPUTDEVICE8W iface,
-                                                LPDIENUMEFFECTSCALLBACKW lpCallback,
-                                                LPVOID pvRef,
-                                                DWORD dwEffType)
-{
-#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
-    /* seems silly to duplicate all this code but all the structures and functions
-     * are actually different (A/W) */
-    DIEFFECTINFOW dei; /* feif */
-    DWORD type = DIEFT_GETTYPE(dwEffType);
-    JoystickImpl* This = impl_from_IDirectInputDevice8W(iface);
-    int xfd = This->joyfd;
-
-    TRACE("(this=%p,%p,%d) type=%d fd=%d\n", This, pvRef, dwEffType, type, xfd);
-
-    dei.dwSize = sizeof(DIEFFECTINFOW);          
-
-    if ((type == DIEFT_ALL || type == DIEFT_CONSTANTFORCE)
-	&& test_bit(This->joydev->ffbits, FF_CONSTANT)) {
-	IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_ConstantForce);
-	(*lpCallback)(&dei, pvRef);
-    }
-
-    if ((type == DIEFT_ALL || type == DIEFT_PERIODIC)
-	&& test_bit(This->joydev->ffbits, FF_PERIODIC)) {
-	if (test_bit(This->joydev->ffbits, FF_SQUARE)) {
-	    IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Square);
-	    (*lpCallback)(&dei, pvRef);
-	}
-	if (test_bit(This->joydev->ffbits, FF_SINE)) {
-            IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Sine);
-	    (*lpCallback)(&dei, pvRef);
-	}
-	if (test_bit(This->joydev->ffbits, FF_TRIANGLE)) {
-	    IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Triangle);
-	    (*lpCallback)(&dei, pvRef);
-	}
-	if (test_bit(This->joydev->ffbits, FF_SAW_UP)) {
-	    IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothUp);
-	    (*lpCallback)(&dei, pvRef);
-	}
-	if (test_bit(This->joydev->ffbits, FF_SAW_DOWN)) {
-	    IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothDown);
-	    (*lpCallback)(&dei, pvRef);
-	}
-    } 
-
-    if ((type == DIEFT_ALL || type == DIEFT_RAMPFORCE)
-	&& test_bit(This->joydev->ffbits, FF_RAMP)) {
-        IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_RampForce);
-        (*lpCallback)(&dei, pvRef);
-    }
-
-    if (type == DIEFT_ALL || type == DIEFT_CONDITION) {
-	if (test_bit(This->joydev->ffbits, FF_SPRING)) {
-	    IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Spring);
-	    (*lpCallback)(&dei, pvRef);
-	}
-	if (test_bit(This->joydev->ffbits, FF_DAMPER)) {
-	    IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Damper);
-	    (*lpCallback)(&dei, pvRef);
-	}
-	if (test_bit(This->joydev->ffbits, FF_INERTIA)) {
-	    IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Inertia);
-	    (*lpCallback)(&dei, pvRef);
-	}
-	if (test_bit(This->joydev->ffbits, FF_FRICTION)) {
-	    IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Friction);
-	    (*lpCallback)(&dei, pvRef);
-	}
-    }
-
-    /* return to unacquired state if that's where it was */
-    if (xfd == -1)
-	IDirectInputDevice8_Unacquire(iface);
-#endif
-
-    return DI_OK;
-}
-
-/*******************************************************************************
- *      GetEffectInfo - Get information about a particular effect 
- */
-static HRESULT WINAPI JoystickWImpl_GetEffectInfo(LPDIRECTINPUTDEVICE8W iface,
-                                                  LPDIEFFECTINFOW pdei,
-                                                  REFGUID guid)
-{
-    JoystickImpl* This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(this=%p,%p,%s)\n", This, pdei, _dump_dinput_GUID(guid));
-
-#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
-    return linuxinput_get_info_W(This->joyfd, guid, pdei);
-#else
-    return DI_OK;
-#endif
-}
-
-/*******************************************************************************
- *      GetForceFeedbackState - Get information about the device's FF state 
- */
-static HRESULT WINAPI JoystickWImpl_GetForceFeedbackState(LPDIRECTINPUTDEVICE8W iface, LPDWORD pdwOut)
-{
-    JoystickImpl* This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(this=%p,%p)\n", This, pdwOut);
-
-    (*pdwOut) = 0;
-
-#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
-    /* DIGFFS_STOPPED is the only mandatory flag to report */
-    if (This->ff_state == FF_STATUS_STOPPED)
-	(*pdwOut) |= DIGFFS_STOPPED;
-#endif
-
-    return DI_OK;
-}
-
-/*******************************************************************************
- *      SendForceFeedbackCommand - Send a command to the device's FF system
- */
-static HRESULT WINAPI JoystickWImpl_SendForceFeedbackCommand(LPDIRECTINPUTDEVICE8W iface, DWORD dwFlags)
-{
-    JoystickImpl* This = impl_from_IDirectInputDevice8W(iface);
-    TRACE("(this=%p,%d)\n", This, dwFlags);
-
-#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
-    switch (dwFlags)
-    {
-    case DISFFC_STOPALL:
-    {
-        effect_list_item *itr;
-
-        /* Stop all effects */
-        LIST_FOR_EACH_ENTRY(itr, &This->ff_effects, effect_list_item, entry)
-            IDirectInputEffect_Stop(itr->ref);
-        break;
-    }
-
-    case DISFFC_RESET:
-    {
-        effect_list_item *itr;
-
-        /* Stop and unload all effects. It is not true that effects are released */
-        LIST_FOR_EACH_ENTRY(itr, &This->ff_effects, effect_list_item, entry)
-        {
-            IDirectInputEffect_Stop(itr->ref);
-            IDirectInputEffect_Unload(itr->ref);
-        }
-        break;
-    }
-    case DISFFC_PAUSE:
-    case DISFFC_CONTINUE:
-        FIXME("No support for Pause or Continue in linux\n");
-        break;
-
-    case DISFFC_SETACTUATORSOFF:
-    case DISFFC_SETACTUATORSON:
-        FIXME("No direct actuator control in linux\n");
-        break;
-
-    default:
-        WARN("Unknown Force Feedback Command %u!\n", dwFlags);
-        return DIERR_INVALIDPARAM;
-    }
-    return DI_OK;
-#else
-    return DIERR_UNSUPPORTED;
-#endif
-}
-
-/*******************************************************************************
- *      EnumCreatedEffectObjects - Enumerate all the effects that have been
- *		created for this device.
- */
-static HRESULT WINAPI JoystickWImpl_EnumCreatedEffectObjects(LPDIRECTINPUTDEVICE8W iface,
-                                                             LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
-                                                             LPVOID pvRef, DWORD dwFlags)
-{
-    /* this function is safe to call on non-ff-enabled builds */
-    JoystickImpl* This = impl_from_IDirectInputDevice8W(iface);
-    effect_list_item *itr, *ptr;
-
-    TRACE("(this=%p,%p,%p,%d)\n", This, lpCallback, pvRef, dwFlags);
-
-    if (!lpCallback)
-	return DIERR_INVALIDPARAM;
-
-    if (dwFlags != 0)
-	FIXME("Flags specified, but no flags exist yet (DX9)!\n");
-
-    LIST_FOR_EACH_ENTRY_SAFE(itr, ptr, &This->ff_effects, effect_list_item, entry)
-        (*lpCallback)(itr->ref, pvRef);
-
-    return DI_OK;
-}
-
-/******************************************************************************
-  *     GetDeviceInfo : get information about a device's identity
-  */
-static HRESULT WINAPI JoystickWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface,
-                                                  LPDIDEVICEINSTANCEW pdidi)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(%p) %p\n", This, pdidi);
-
-    if (pdidi == NULL) return E_POINTER;
-    if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) &&
-        (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW)))
-        return DIERR_INVALIDPARAM;
-
-    fill_joystick_dideviceinstanceW(pdidi, This->generic.base.dinput->dwVersion,
-                                    get_joystick_index(&This->generic.base.guid));
-
-    pdidi->guidInstance = This->generic.base.guid;
-
-    return DI_OK;
-}
-
-static const IDirectInputDevice8WVtbl JoystickWvt =
-{
-    IDirectInputDevice2WImpl_QueryInterface,
-    IDirectInputDevice2WImpl_AddRef,
-    JoystickWGenericImpl_Release,
-    JoystickWGenericImpl_GetCapabilities,
-    IDirectInputDevice2WImpl_EnumObjects,
-    JoystickWImpl_GetProperty,
-    JoystickWImpl_SetProperty,
-    JoystickWImpl_Acquire,
-    JoystickWImpl_Unacquire,
-    JoystickWGenericImpl_GetDeviceState,
-    IDirectInputDevice2WImpl_GetDeviceData,
-    IDirectInputDevice2WImpl_SetDataFormat,
-    IDirectInputDevice2WImpl_SetEventNotification,
-    IDirectInputDevice2WImpl_SetCooperativeLevel,
-    JoystickWGenericImpl_GetObjectInfo,
-    JoystickWImpl_GetDeviceInfo,
-    IDirectInputDevice2WImpl_RunControlPanel,
-    IDirectInputDevice2WImpl_Initialize,
-    JoystickWImpl_CreateEffect,
-    JoystickWImpl_EnumEffects,
-    JoystickWImpl_GetEffectInfo,
-    JoystickWImpl_GetForceFeedbackState,
-    JoystickWImpl_SendForceFeedbackCommand,
-    JoystickWImpl_EnumCreatedEffectObjects,
-    IDirectInputDevice2WImpl_Escape,
-    JoystickWGenericImpl_Poll,
-    IDirectInputDevice2WImpl_SendDeviceData,
-    IDirectInputDevice7WImpl_EnumEffectsInFile,
-    IDirectInputDevice7WImpl_WriteEffectToFile,
-    JoystickWGenericImpl_BuildActionMap,
-    JoystickWGenericImpl_SetActionMap,
-    IDirectInputDevice8WImpl_GetImageInfo
-};
-
-#else  /* HAS_PROPER_HEADER */
-
-const struct dinput_device joystick_linuxinput_device = {
-  "Wine Linux-input joystick driver",
-  NULL,
-  NULL,
-};
-
-#endif  /* HAS_PROPER_HEADER */
diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c
deleted file mode 100644
index 5796daf8e11..00000000000
--- a/dlls/dinput/joystick_osx.c
+++ /dev/null
@@ -1,1704 +0,0 @@
-/*  DirectInput Joystick device for Mac OS/X
- *
- * Copyright 1998 Marcus Meissner
- * Copyright 1998,1999 Lionel Ulmer
- * Copyright 2000-2001 TransGaming Technologies Inc.
- * Copyright 2009 CodeWeavers, Aric Stewart
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#if defined(HAVE_IOKIT_HID_IOHIDLIB_H)
-#define DWORD UInt32
-#define LPDWORD UInt32*
-#define LONG SInt32
-#define LPLONG SInt32*
-#define E_PENDING __carbon_E_PENDING
-#define ULONG __carbon_ULONG
-#define E_INVALIDARG __carbon_E_INVALIDARG
-#define E_OUTOFMEMORY __carbon_E_OUTOFMEMORY
-#define E_HANDLE __carbon_E_HANDLE
-#define E_ACCESSDENIED __carbon_E_ACCESSDENIED
-#define E_UNEXPECTED __carbon_E_UNEXPECTED
-#define E_FAIL __carbon_E_FAIL
-#define E_ABORT __carbon_E_ABORT
-#define E_POINTER __carbon_E_POINTER
-#define E_NOINTERFACE __carbon_E_NOINTERFACE
-#define E_NOTIMPL __carbon_E_NOTIMPL
-#define S_FALSE __carbon_S_FALSE
-#define S_OK __carbon_S_OK
-#define HRESULT_FACILITY __carbon_HRESULT_FACILITY
-#define IS_ERROR __carbon_IS_ERROR
-#define FAILED __carbon_FAILED
-#define SUCCEEDED __carbon_SUCCEEDED
-#define MAKE_HRESULT __carbon_MAKE_HRESULT
-#define HRESULT __carbon_HRESULT
-#define STDMETHODCALLTYPE __carbon_STDMETHODCALLTYPE
-#include <IOKit/IOKitLib.h>
-#include <IOKit/hid/IOHIDLib.h>
-#include <ForceFeedback/ForceFeedback.h>
-#undef ULONG
-#undef E_INVALIDARG
-#undef E_OUTOFMEMORY
-#undef E_HANDLE
-#undef E_ACCESSDENIED
-#undef E_UNEXPECTED
-#undef E_FAIL
-#undef E_ABORT
-#undef E_POINTER
-#undef E_NOINTERFACE
-#undef E_NOTIMPL
-#undef S_FALSE
-#undef S_OK
-#undef HRESULT_FACILITY
-#undef IS_ERROR
-#undef FAILED
-#undef SUCCEEDED
-#undef MAKE_HRESULT
-#undef HRESULT
-#undef STDMETHODCALLTYPE
-#undef DWORD
-#undef LPDWORD
-#undef LONG
-#undef LPLONG
-#undef E_PENDING
-#endif /* HAVE_IOKIT_HID_IOHIDLIB_H */
-
-#include "wine/debug.h"
-#include "wine/unicode.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "winreg.h"
-#include "devguid.h"
-#include "dinput.h"
-
-#include "dinput_private.h"
-#include "device_private.h"
-#include "joystick_private.h"
-
-#ifdef HAVE_IOHIDMANAGERCREATE
-
-WINE_DEFAULT_DEBUG_CHANNEL(dinput);
-
-#define MAKEUINT64(high, low) (((uint64_t)high << 32) | (uint32_t)low)
-
-static CFMutableArrayRef device_main_elements = NULL;
-
-/* Maps IOHIDDeviceRefs to CRITICAL_SECTION pointers. */
-static CFMutableDictionaryRef hid_device_crits = NULL;
-
-typedef struct JoystickImpl JoystickImpl;
-static const IDirectInputDevice8WVtbl JoystickWvt;
-
-struct JoystickImpl
-{
-    struct JoystickGenericImpl generic;
-
-    /* osx private */
-    int                    id;
-    CFArrayRef             elements;
-    int                    *element_values;
-    ObjProps               **propmap;
-    FFDeviceObjectReference ff;
-    struct list effects;
-};
-
-static inline JoystickImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface)
-{
-    return CONTAINING_RECORD(CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8W_iface),
-           JoystickGenericImpl, base), JoystickImpl, generic);
-}
-
-typedef struct _EffectImpl {
-    IDirectInputEffect IDirectInputEffect_iface;
-    LONG ref;
-
-    JoystickImpl *device;
-    FFEffectObjectReference effect;
-    GUID guid;
-
-    struct list entry;
-} EffectImpl;
-
-static EffectImpl *impl_from_IDirectInputEffect(IDirectInputEffect *iface)
-{
-    return CONTAINING_RECORD(iface, EffectImpl, IDirectInputEffect_iface);
-}
-
-static const IDirectInputEffectVtbl EffectVtbl;
-
-static const GUID DInput_Wine_OsX_Joystick_GUID = { /* 59CAD8F6-E617-41E2-8EB7-47B23EEEDC5A */
-  0x59CAD8F6, 0xE617, 0x41E2, {0x8E, 0xB7, 0x47, 0xB2, 0x3E, 0xEE, 0xDC, 0x5A}
-};
-
-static HRESULT osx_to_win32_hresult(HRESULT in)
-{
-    /* OSX returns 16-bit COM runtime errors, which we should
-     * convert to win32 */
-    switch(in){
-    case 0x80000001:
-        return E_NOTIMPL;
-    case 0x80000002:
-        return E_OUTOFMEMORY;
-    case 0x80000003:
-        return E_INVALIDARG;
-    case 0x80000004:
-        return E_NOINTERFACE;
-    case 0x80000005:
-        return E_POINTER;
-    case 0x80000006:
-        return E_HANDLE;
-    case 0x80000007:
-        return E_ABORT;
-    case 0x80000008:
-        return E_FAIL;
-    case 0x80000009:
-        return E_ACCESSDENIED;
-    case 0x8000FFFF:
-        return E_UNEXPECTED;
-    }
-    return in;
-}
-
-static 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 void copy_set_to_array(const void *value, void *context)
-{
-    CFArrayAppendValue(context, value);
-}
-
-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;
-}
-
-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;
-    /* virtual joysticks may not have a kIOHIDLocationIDKey and will default to location ID of 0, this orders virtual joysticks by their name */
-    return device_name_comparator(device1, device2);
-}
-
-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), ARRAY_SIZE(buf));
-        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 IOHIDDeviceRef get_device_ref(int id)
-{
-    IOHIDElementRef device_main_element;
-    IOHIDDeviceRef hid_device;
-
-    TRACE("id %d\n", id);
-
-    if (!device_main_elements || id >= CFArrayGetCount(device_main_elements))
-        return 0;
-
-    device_main_element = (IOHIDElementRef)CFArrayGetValueAtIndex(device_main_elements, id);
-    if (!device_main_element)
-    {
-        ERR("Invalid Element requested %i\n",id);
-        return 0;
-    }
-
-    hid_device = IOHIDElementGetDevice(device_main_element);
-    if (!hid_device)
-    {
-        ERR("Invalid Device requested %i\n",id);
-        return 0;
-    }
-
-    TRACE("-> %s\n", debugstr_device(hid_device));
-    return hid_device;
-}
-
-static HRESULT get_ff(IOHIDDeviceRef device, FFDeviceObjectReference *ret)
-{
-    io_service_t service;
-    CFMutableDictionaryRef matching;
-    CFTypeRef location_id;
-    HRESULT hr;
-
-    TRACE("device %s\n", debugstr_device(device));
-
-    matching = IOServiceMatching(kIOHIDDeviceKey);
-    if(!matching){
-        WARN("IOServiceMatching failed, force feedback disabled\n");
-        return DIERR_DEVICENOTREG;
-    }
-
-    location_id = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDLocationIDKey));
-    if(!location_id){
-        CFRelease(matching);
-        WARN("IOHIDDeviceGetProperty failed, force feedback disabled\n");
-        return DIERR_DEVICENOTREG;
-    }
-
-    CFDictionaryAddValue(matching, CFSTR(kIOHIDLocationIDKey), location_id);
-
-    service = IOServiceGetMatchingService(kIOMasterPortDefault, matching);
-
-    if (ret)
-        hr = osx_to_win32_hresult(FFCreateDevice(service, ret));
-    else
-        hr = FFIsForceFeedback(service) == FF_OK ? S_OK : S_FALSE;
-
-    IOObjectRelease(service);
-    TRACE("-> hr 0x%08x *ret %p\n", hr, ret ? *ret : NULL);
-    return hr;
-}
-
-static CFMutableDictionaryRef create_osx_device_match(int usage)
-{
-    CFMutableDictionaryRef result;
-
-    TRACE("usage %d\n", usage);
-
-    result = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
-            &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
-
-    if ( result )
-    {
-        int number = kHIDPage_GenericDesktop;
-        CFNumberRef page = CFNumberCreate( kCFAllocatorDefault,
-                          kCFNumberIntType, &number);
-
-        if (page)
-        {
-            CFNumberRef cf_usage;
-
-            CFDictionarySetValue( result, CFSTR( kIOHIDDeviceUsagePageKey ), page );
-            CFRelease( page );
-
-            cf_usage = CFNumberCreate( kCFAllocatorDefault,
-                        kCFNumberIntType, &usage);
-            if (cf_usage)
-            {
-                CFDictionarySetValue( result, CFSTR( kIOHIDDeviceUsageKey ), cf_usage );
-                CFRelease( cf_usage );
-            }
-            else
-            {
-                ERR("CFNumberCreate() failed.\n");
-                CFRelease(result);
-                return NULL;
-            }
-        }
-        else
-        {
-            ERR("CFNumberCreate failed.\n");
-            CFRelease(result);
-            return NULL;
-        }
-    }
-    else
-    {
-        ERR("CFDictionaryCreateMutable failed.\n");
-        return NULL;
-    }
-
-    return result;
-}
-
-static CFIndex find_top_level(IOHIDDeviceRef hid_device, CFMutableArrayRef main_elements)
-{
-    CFArrayRef      elements;
-    CFIndex         total = 0;
-
-    TRACE("hid_device %s\n", debugstr_device(hid_device));
-
-    if (!hid_device)
-        return 0;
-
-    elements = IOHIDDeviceCopyMatchingElements(hid_device, NULL, 0);
-
-    if (elements)
-    {
-        CFIndex idx, cnt = CFArrayGetCount(elements);
-        for (idx=0; idx<cnt; idx++)
-        {
-            IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, idx);
-            int type = IOHIDElementGetType(element);
-
-            TRACE("element %s\n", debugstr_element(element));
-
-            /* Check for top-level gaming device collections */
-            if (type == kIOHIDElementTypeCollection && IOHIDElementGetParent(element) == 0)
-            {
-                int usage_page = IOHIDElementGetUsagePage(element);
-                int usage = IOHIDElementGetUsage(element);
-
-                if (usage_page == kHIDPage_GenericDesktop &&
-                    (usage == kHIDUsage_GD_Joystick || usage == kHIDUsage_GD_GamePad))
-                {
-                    CFArrayAppendValue(main_elements, element);
-                    total++;
-                }
-            }
-        }
-        CFRelease(elements);
-    }
-
-    TRACE("-> total %d\n", (int)total);
-    return total;
-}
-
-static void get_element_children(IOHIDElementRef element, CFMutableArrayRef all_children)
-{
-    CFIndex    idx, cnt;
-    CFArrayRef element_children = IOHIDElementGetChildren(element);
-
-    TRACE("element %s\n", debugstr_element(element));
-
-    cnt = CFArrayGetCount(element_children);
-
-    /* Either add the element to the array or grab its children */
-    for (idx=0; idx<cnt; idx++)
-    {
-        IOHIDElementRef child;
-
-        child = (IOHIDElementRef)CFArrayGetValueAtIndex(element_children, idx);
-        TRACE("child %s\n", debugstr_element(child));
-        if (IOHIDElementGetType(child) == kIOHIDElementTypeCollection)
-            get_element_children(child, all_children);
-        else
-            CFArrayAppendValue(all_children, child);
-    }
-}
-
-static int find_osx_devices(void)
-{
-    IOHIDManagerRef hid_manager;
-    CFMutableDictionaryRef result;
-    CFSetRef devset;
-    CFMutableArrayRef matching;
-
-    TRACE("()\n");
-
-    hid_manager = IOHIDManagerCreate( kCFAllocatorDefault, 0L );
-    if (IOHIDManagerOpen( hid_manager, 0 ) != kIOReturnSuccess)
-    {
-        ERR("Couldn't open IOHIDManager.\n");
-        CFRelease( hid_manager );
-        return 0;
-    }
-
-     matching = CFArrayCreateMutable( kCFAllocatorDefault, 0,
-                        &kCFTypeArrayCallBacks );
-
-    /* build matching dictionary */
-    result = create_osx_device_match(kHIDUsage_GD_Joystick);
-    if (!result)
-    {
-        CFRelease(matching);
-        goto fail;
-    }
-    CFArrayAppendValue( matching, result );
-    CFRelease( result );
-    result = create_osx_device_match(kHIDUsage_GD_GamePad);
-    if (!result)
-    {
-        CFRelease(matching);
-        goto fail;
-    }
-    CFArrayAppendValue( matching, result );
-    CFRelease( result );
-
-    IOHIDManagerSetDeviceMatchingMultiple( hid_manager, matching);
-    CFRelease( matching );
-    devset = IOHIDManagerCopyDevices( hid_manager );
-    if (devset)
-    {
-        CFIndex num_devices, num_main_elements, idx;
-        CFMutableArrayRef devices;
-
-        num_devices = CFSetGetCount(devset);
-        devices = CFArrayCreateMutable(kCFAllocatorDefault, num_devices, &kCFTypeArrayCallBacks);
-        CFSetApplyFunction(devset, copy_set_to_array, devices);
-        CFRelease(devset);
-        CFArraySortValues(devices, CFRangeMake(0, num_devices), device_location_name_comparator, NULL);
-
-        device_main_elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-        hid_device_crits = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
-        if (!device_main_elements || !hid_device_crits)
-        {
-            if (device_main_elements) CFRelease(device_main_elements);
-            if (hid_device_crits) CFRelease(hid_device_crits);
-            CFRelease( devices );
-            goto fail;
-        }
-
-        num_main_elements = 0;
-        for (idx = 0; idx < num_devices; idx++)
-        {
-            CFIndex top;
-            IOHIDDeviceRef hid_device;
-
-            hid_device = (IOHIDDeviceRef) CFArrayGetValueAtIndex(devices, idx);
-            TRACE("hid_device %s\n", debugstr_device(hid_device));
-            top = find_top_level(hid_device, device_main_elements);
-            num_main_elements += top;
-
-            if ( top ) {
-                /* This HID device has relevent elements, so it needs a critical section. */
-                CRITICAL_SECTION *cs = HeapAlloc(GetProcessHeap(), 0, sizeof(CRITICAL_SECTION));
-                InitializeCriticalSection(cs);
-                cs->DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": hid_device_crits");
-
-                CFDictionaryAddValue(hid_device_crits, hid_device, cs);
-            }
-        }
-
-        CFRelease(devices);
-
-        TRACE("found %i device(s), %i collection(s)\n",(int)num_devices,(int)num_main_elements);
-        return (int)num_main_elements;
-    }
-
-fail:
-    IOHIDManagerClose( hid_manager, 0 );
-    CFRelease( hid_manager );
-    return 0;
-}
-
-static int get_osx_device_name(int id, char *name, int length)
-{
-    CFStringRef str;
-    IOHIDDeviceRef hid_device;
-
-    hid_device = get_device_ref(id);
-
-    TRACE("id %d hid_device %s\n", id, debugstr_device(hid_device));
-
-    if (name)
-        name[0] = 0;
-
-    if (!hid_device)
-        return 0;
-
-    str = IOHIDDeviceGetProperty(hid_device, CFSTR( kIOHIDProductKey ));
-    if (str)
-    {
-        CFIndex len = CFStringGetLength(str);
-        if (length >= len)
-        {
-            CFStringGetCString(str,name,length,kCFStringEncodingASCII);
-            return len;
-        }
-        else
-            return (len+1);
-    }
-    return 0;
-}
-
-static CFComparisonResult button_usage_comparator(const void *val1, const void *val2, void *context)
-{
-    IOHIDElementRef element1 = (IOHIDElementRef)val1, element2 = (IOHIDElementRef)val2;
-    int usage1 = IOHIDElementGetUsage(element1), usage2 = IOHIDElementGetUsage(element2);
-
-    if (usage1 < usage2)
-        return kCFCompareLessThan;
-    if (usage1 > usage2)
-        return kCFCompareGreaterThan;
-    return kCFCompareEqualTo;
-}
-
-static void get_osx_device_elements(JoystickImpl *device, uint64_t axis_map[8])
-{
-    IOHIDElementRef device_main_element;
-    CFMutableArrayRef elements;
-    DWORD           sliders = 0;
-    BOOL            use_accel_brake_for_rx_ry = TRUE;
-
-    TRACE("device %p device->id %d\n", device, device->id);
-
-    device->elements = NULL;
-
-    if (!device_main_elements || device->id >= CFArrayGetCount(device_main_elements))
-        return;
-
-    device_main_element = (IOHIDElementRef)CFArrayGetValueAtIndex(device_main_elements, device->id);
-    TRACE("device_main_element %s\n", debugstr_element(device_main_element));
-    if (!device_main_element)
-        return;
-
-    elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-    get_element_children(device_main_element, elements);
-
-    if (elements)
-    {
-        CFIndex idx, cnt = CFArrayGetCount( elements );
-        CFMutableArrayRef axes = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-        CFMutableArrayRef buttons = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-        CFMutableArrayRef povs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-
-        /* Scan the elements to see if Rx/Ry is present, if not then Accelerator/Brake can be mapped to it.
-         * (Xbox One controller triggers use accelerator/brake)
-         */
-        for ( idx = 0; idx < cnt; idx++ )
-        {
-            IOHIDElementRef element = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elements, idx );
-            IOHIDElementType type = IOHIDElementGetType( element );
-            uint32_t usage_page = IOHIDElementGetUsagePage( element );
-            uint32_t usage = IOHIDElementGetUsage( element );
-
-            if (type == kIOHIDElementTypeInput_Misc && usage_page == kHIDPage_GenericDesktop &&
-                (usage == kHIDUsage_GD_Rx || usage == kHIDUsage_GD_Ry))
-            {
-                use_accel_brake_for_rx_ry = FALSE;
-            }
-        }
-
-        for ( idx = 0; idx < cnt; idx++ )
-        {
-            IOHIDElementRef element = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elements, idx );
-            int type = IOHIDElementGetType( element );
-            int usage_page = IOHIDElementGetUsagePage( element );
-
-            TRACE("element %s\n", debugstr_element(element));
-
-            if (usage_page >= kHIDPage_VendorDefinedStart)
-            {
-                /* vendor pages can repurpose type ids, resulting in incorrect case matches below (e.g. ds4 controllers) */
-                continue;
-            }
-
-            switch(type)
-            {
-                case kIOHIDElementTypeInput_Button:
-                {
-                    TRACE("kIOHIDElementTypeInput_Button usage_page %d\n", usage_page);
-                    if ((usage_page != kHIDPage_Button) && (usage_page != kHIDPage_Consumer))
-                    {
-                        /* avoid strange elements found on the 360 controller */
-                        continue;
-                    }
-
-                    if (CFArrayGetCount(buttons) < 128)
-                        CFArrayAppendValue(buttons, element);
-                    break;
-                }
-                case kIOHIDElementTypeInput_Axis:
-                {
-                    TRACE("kIOHIDElementTypeInput_Axis\n");
-                    CFArrayAppendValue(axes, element);
-                    break;
-                }
-                case kIOHIDElementTypeInput_Misc:
-                {
-                    uint32_t usage = IOHIDElementGetUsage( element );
-                    switch(MAKEUINT64(usage_page, usage))
-                    {
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Hatswitch):
-                        {
-                            TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Hatswitch\n");
-                            CFArrayAppendValue(povs, element);
-                            break;
-                        }
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Slider):
-                            sliders ++;
-                            if (sliders > 2)
-                                break;
-                            /* fallthrough, sliders are axis */
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_X):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Y):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Z):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Rx):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Ry):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Rz):
-                        case MAKEUINT64(kHIDPage_Simulation, kHIDUsage_Sim_Accelerator):
-                        case MAKEUINT64(kHIDPage_Simulation, kHIDUsage_Sim_Brake):
-                        {
-                            if (usage == kHIDUsage_Sim_Accelerator || usage == kHIDUsage_Sim_Brake)
-                            {
-                                if (use_accel_brake_for_rx_ry)
-                                    TRACE("Using Sim_Accelerator/Brake for GD_Rx/Ry\n");
-                                else
-                                    break;
-                            }
-
-                            TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_* (%d)\n", usage);
-                            axis_map[CFArrayGetCount(axes)]=MAKEUINT64(usage_page, usage);
-                            CFArrayAppendValue(axes, element);
-                            break;
-                        }
-                        default:
-                            FIXME("kIOHIDElementTypeInput_Misc / Unhandled usage %i/%i\n", usage_page, usage);
-                    }
-                    break;
-                }
-                default:
-                    FIXME("Unhandled type %i\n",type);
-            }
-        }
-
-        /* Sort buttons into correct order */
-        CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)), button_usage_comparator, NULL);
-
-        device->generic.devcaps.dwAxes = CFArrayGetCount(axes);
-        device->generic.devcaps.dwButtons = CFArrayGetCount(buttons);
-        device->generic.devcaps.dwPOVs = CFArrayGetCount(povs);
-
-        TRACE("axes %u povs %u buttons %u\n", device->generic.devcaps.dwAxes, device->generic.devcaps.dwPOVs,
-              device->generic.devcaps.dwButtons);
-
-        /* build our element array in the order that dinput expects */
-        CFArrayAppendArray(axes, povs, CFRangeMake(0, device->generic.devcaps.dwPOVs));
-        CFArrayAppendArray(axes, buttons, CFRangeMake(0, device->generic.devcaps.dwButtons));
-        device->elements = axes;
-        axes = NULL;
-
-        CFRelease(povs);
-        CFRelease(buttons);
-        CFRelease(elements);
-
-        device->element_values = HeapAlloc(GetProcessHeap(), 0,
-                                           CFArrayGetCount(device->elements) * sizeof(int));
-    }
-    else
-    {
-        device->generic.devcaps.dwAxes = 0;
-        device->generic.devcaps.dwButtons = 0;
-        device->generic.devcaps.dwPOVs = 0;
-    }
-}
-
-static void get_osx_device_elements_props(JoystickImpl *device)
-{
-    TRACE("device %p\n", device);
-
-    if (device->elements)
-    {
-        CFIndex idx, cnt = CFArrayGetCount( device->elements );
-
-        for ( idx = 0; idx < cnt; idx++ )
-        {
-            IOHIDElementRef element = ( IOHIDElementRef ) CFArrayGetValueAtIndex( device->elements, idx );
-
-            TRACE("element %s\n", debugstr_element(element));
-
-            device->generic.props[idx].lDevMin = IOHIDElementGetLogicalMin(element);
-            device->generic.props[idx].lDevMax = IOHIDElementGetLogicalMax(element);
-            device->generic.props[idx].lMin =  0;
-            device->generic.props[idx].lMax =  0xffff;
-            device->generic.props[idx].lDeadZone = 0;
-            device->generic.props[idx].lSaturation = 0;
-        }
-    }
-}
-
-static IOReturn get_element_values(IOHIDDeviceRef hid_device, JoystickImpl *device)
-{
-    CFIndex i, element_count = CFArrayGetCount(device->elements);
-    IOReturn ret = kIOReturnSuccess;
-    IOHIDElementRef element;
-    IOHIDValueRef valueRef;
-
-    /* If more than one thread is trying to poll the same HID device, we can
-     * crash deep inside IOKit. So we enter a per-IOHIDDevice critical section
-     * here. Note that it must be per-HID device and not just per-JoystickImpl,
-     * as there may be multiple JoystickImpls referencing the same underlying
-     * device. */
-
-    CRITICAL_SECTION *crit = (CRITICAL_SECTION *)CFDictionaryGetValue(hid_device_crits, hid_device);
-    if (!crit) {
-        ERR("missing critical section for device %s\n", debugstr_device(hid_device));
-        return kIOReturnError;
-    }
-
-    EnterCriticalSection(crit);
-
-    for (i = 0; i < element_count; i++)
-    {
-        element = (IOHIDElementRef)CFArrayGetValueAtIndex(device->elements, i);
-        ret = IOHIDDeviceGetValue(hid_device, element, &valueRef);
-        if (ret != kIOReturnSuccess)
-        {
-            ERR("error getting value of element %s: %08x\n", debugstr_element(element), ret);
-            break;
-        }
-
-        device->element_values[i] = IOHIDValueGetIntegerValue(valueRef);
-    }
-
-    LeaveCriticalSection(crit);
-    return ret;
-}
-
-static void poll_osx_device_state( IDirectInputDevice8W *iface )
-{
-    JoystickImpl *device = impl_from_IDirectInputDevice8W( iface );
-    IOHIDElementRef device_main_element;
-    IOHIDDeviceRef hid_device;
-
-    TRACE("device %p device->id %i\n", device, device->id);
-
-    if (!device_main_elements || device->id >= CFArrayGetCount(device_main_elements))
-        return;
-
-    device_main_element = (IOHIDElementRef) CFArrayGetValueAtIndex(device_main_elements, device->id);
-    hid_device = IOHIDElementGetDevice(device_main_element);
-    TRACE("main element %s hid_device %s\n", debugstr_element(device_main_element), debugstr_device(hid_device));
-    if (!hid_device)
-        return;
-
-    if (device->elements)
-    {
-        if (get_element_values(hid_device, device) != kIOReturnSuccess)
-            return;
-
-        int button_idx = 0;
-        int pov_idx = 0;
-        int slider_idx = 0;
-        int inst_id;
-        CFIndex idx, cnt = CFArrayGetCount( device->elements );
-
-        for ( idx = 0; idx < cnt; idx++ )
-        {
-            int oldVal, newVal, val = device->element_values[idx];
-            IOHIDElementRef element = ( IOHIDElementRef ) CFArrayGetValueAtIndex( device->elements, idx );
-            int type = IOHIDElementGetType( element );
-
-            TRACE("element %s\n", debugstr_element(element));
-
-            switch(type)
-            {
-                case kIOHIDElementTypeInput_Button:
-                    TRACE("kIOHIDElementTypeInput_Button\n");
-                    if(button_idx < 128)
-                    {
-                        newVal = val ? 0x80 : 0x0;
-                        oldVal = device->generic.js.rgbButtons[button_idx];
-                        device->generic.js.rgbButtons[button_idx] = newVal;
-                        TRACE("val %d oldVal %d newVal %d\n", val, oldVal, newVal);
-                        if (oldVal != newVal)
-                        {
-                            inst_id = DIDFT_MAKEINSTANCE(button_idx) | DIDFT_PSHBUTTON;
-                            queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++);
-                            if (device->generic.base.hEvent)
-                                SetEvent( device->generic.base.hEvent );
-                        }
-                        button_idx ++;
-                    }
-                    break;
-                case kIOHIDElementTypeInput_Misc:
-                {
-                    uint32_t usage_page = IOHIDElementGetUsagePage( element );
-                    uint32_t usage = IOHIDElementGetUsage( element );
-                    switch(MAKEUINT64(usage_page, usage))
-                    {
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Hatswitch):
-                        {
-                            TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Hatswitch\n");
-                            oldVal = device->generic.js.rgdwPOV[pov_idx];
-                            if ((val > device->generic.props[idx].lDevMax) || (val < device->generic.props[idx].lDevMin))
-                                newVal = -1;
-                            else
-                                newVal = (val - device->generic.props[idx].lDevMin) * 4500;
-                            device->generic.js.rgdwPOV[pov_idx] = newVal;
-                            TRACE("val %d oldVal %d newVal %d\n", val, oldVal, newVal);
-                            if (oldVal != newVal)
-                            {
-                                inst_id = DIDFT_MAKEINSTANCE(pov_idx) | DIDFT_POV;
-                                queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++);
-                                if (device->generic.base.hEvent)
-                                    SetEvent( device->generic.base.hEvent );
-                            }
-                            pov_idx ++;
-                            break;
-                        }
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_X):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Y):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Z):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Rx):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Ry):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Rz):
-                        case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Slider):
-                        case MAKEUINT64(kHIDPage_Simulation, kHIDUsage_Sim_Accelerator):
-                        case MAKEUINT64(kHIDPage_Simulation, kHIDUsage_Sim_Brake):
-                        {
-                            int wine_obj = -1;
-
-                            newVal = joystick_map_axis(&device->generic.props[idx], val);
-                            switch (MAKEUINT64(usage_page, usage))
-                            {
-                            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_X):
-                                TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_X\n");
-                                wine_obj = 0;
-                                oldVal = device->generic.js.lX;
-                                device->generic.js.lX = newVal;
-                                break;
-                            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Y):
-                                TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Y\n");
-                                wine_obj = 1;
-                                oldVal = device->generic.js.lY;
-                                device->generic.js.lY = newVal;
-                                break;
-                            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Z):
-                                TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Z\n");
-                                wine_obj = 2;
-                                oldVal = device->generic.js.lZ;
-                                device->generic.js.lZ = newVal;
-                                break;
-                            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Rx):
-                            case MAKEUINT64(kHIDPage_Simulation, kHIDUsage_Sim_Accelerator):
-                                TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Rx\n");
-                                wine_obj = 3;
-                                oldVal = device->generic.js.lRx;
-                                device->generic.js.lRx = newVal;
-                                break;
-                            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Ry):
-                            case MAKEUINT64(kHIDPage_Simulation, kHIDUsage_Sim_Brake):
-                                TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Ry\n");
-                                wine_obj = 4;
-                                oldVal = device->generic.js.lRy;
-                                device->generic.js.lRy = newVal;
-                                break;
-                            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Rz):
-                                TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Rz\n");
-                                wine_obj = 5;
-                                oldVal = device->generic.js.lRz;
-                                device->generic.js.lRz = newVal;
-                                break;
-                            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Slider):
-                                TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Slider\n");
-                                wine_obj = 6 + slider_idx;
-                                oldVal = device->generic.js.rglSlider[slider_idx];
-                                device->generic.js.rglSlider[slider_idx] = newVal;
-                                slider_idx ++;
-                                break;
-                            }
-                            TRACE("val %d oldVal %d newVal %d\n", val, oldVal, newVal);
-                            if ((wine_obj != -1) &&
-                                 (oldVal != newVal))
-                            {
-                                inst_id = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
-                                queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++);
-                                if (device->generic.base.hEvent)
-                                    SetEvent( device->generic.base.hEvent );
-                            }
-
-                            break;
-                        }
-                        default:
-                            FIXME("kIOHIDElementTypeInput_Misc / unhandled usage %i\n", usage);
-                    }
-                    break;
-                }
-                default:
-                    FIXME("Unhandled type %i\n",type);
-            }
-        }
-    }
-}
-
-static INT find_joystick_devices(void)
-{
-    static INT joystick_devices_count = -1;
-
-    if (joystick_devices_count != -1) return joystick_devices_count;
-
-    joystick_devices_count = find_osx_devices();
-
-    return  joystick_devices_count;
-}
-
-static DWORD make_vid_pid(IOHIDDeviceRef device)
-{
-    long vendID, prodID;
-
-    vendID = get_device_property_long(device, CFSTR(kIOHIDVendorIDKey));
-    prodID = get_device_property_long(device, CFSTR(kIOHIDProductIDKey));
-
-    return MAKELONG(vendID, prodID);
-}
-
-static HRESULT joydev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
-{
-    char name[MAX_PATH];
-    char friendly[32];
-    IOHIDDeviceRef device;
-    BOOL is_joystick;
-
-    TRACE("dwDevType %u dwFlags 0x%08x version 0x%04x id %d\n", dwDevType, dwFlags, version, id);
-
-    if (id >= find_joystick_devices()) return E_FAIL;
-
-    device = get_device_ref(id);
-
-    if ((dwDevType == 0) ||
-    ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) ||
-    (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
-
-        if (dwFlags & DIEDFL_FORCEFEEDBACK) {
-            if(!device)
-                return S_FALSE;
-            if(get_ff(device, NULL) != S_OK)
-                return S_FALSE;
-        }
-        is_joystick = get_device_property_long(device, CFSTR(kIOHIDDeviceUsageKey)) == kHIDUsage_GD_Joystick;
-        /* Return joystick */
-        lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID;
-        lpddi->guidInstance.Data3 = id;
-        lpddi->guidProduct = dinput_pidvid_guid;
-        lpddi->guidProduct.Data1 = make_vid_pid(device);
-        lpddi->dwDevType = get_device_type(version, is_joystick);
-        lpddi->dwDevType |= DIDEVTYPE_HID;
-        lpddi->wUsagePage = 0x01; /* Desktop */
-        if (is_joystick)
-            lpddi->wUsage = 0x04; /* Joystick */
-        else
-            lpddi->wUsage = 0x05; /* Game Pad */
-        sprintf(friendly, "Joystick %d", id);
-        MultiByteToWideChar(CP_ACP, 0, friendly, -1, lpddi->tszInstanceName, MAX_PATH);
-
-        /* get the device name */
-        get_osx_device_name(id, name, MAX_PATH);
-
-        MultiByteToWideChar(CP_ACP, 0, name, -1, lpddi->tszProductName, MAX_PATH);
-        lpddi->guidFFDriver = GUID_NULL;
-        return S_OK;
-    }
-
-    return S_FALSE;
-}
-
-static const char *osx_ff_axis_name(UInt8 axis)
-{
-    static char ret[6];
-    switch(axis){
-    case FFJOFS_X:
-        return "FFJOFS_X";
-    case FFJOFS_Y:
-        return "FFJOFS_Y";
-    case FFJOFS_Z:
-        return "FFJOFS_Z";
-    }
-    sprintf(ret, "%u", (unsigned int)axis);
-    return ret;
-}
-
-static BOOL osx_axis_has_ff(FFCAPABILITIES *ffcaps, UInt8 axis)
-{
-    int i;
-    for(i = 0; i < ffcaps->numFfAxes; ++i)
-        if(ffcaps->ffAxes[i] == axis)
-            return TRUE;
-    return FALSE;
-}
-
-static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, JoystickImpl **out, unsigned short index )
-{
-    DWORD i;
-    IOHIDDeviceRef device;
-    JoystickImpl* newDevice;
-    char name[MAX_PATH];
-    HRESULT hr;
-    LPDIDATAFORMAT df = NULL;
-    int idx = 0;
-    uint64_t axis_map[8]; /* max axes */
-    int slider_count = 0;
-    FFCAPABILITIES ffcaps;
-
-    TRACE( "%s %p %p %hu\n", debugstr_guid( rguid ), dinput, out, index );
-
-    if (FAILED(hr = direct_input_device_alloc( sizeof(JoystickImpl), &JoystickWvt, rguid, dinput, (void **)&newDevice )))
-        return hr;
-    df = newDevice->generic.base.data_format.wine_df;
-    newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");
-
-    newDevice->id = index;
-
-    device = get_device_ref(index);
-
-    newDevice->generic.guidInstance = DInput_Wine_OsX_Joystick_GUID;
-    newDevice->generic.guidInstance.Data3 = index;
-    newDevice->generic.guidProduct = dinput_pidvid_guid;
-    newDevice->generic.guidProduct.Data1 = make_vid_pid(device);
-    newDevice->generic.joy_polldev = poll_osx_device_state;
-
-    /* get the device name */
-    get_osx_device_name(index, name, MAX_PATH);
-    TRACE("Name %s\n",name);
-
-    /* copy the device name */
-    newDevice->generic.name = HeapAlloc(GetProcessHeap(),0,strlen(name) + 1);
-    strcpy(newDevice->generic.name, name);
-
-    list_init(&newDevice->effects);
-    if(get_ff(device, &newDevice->ff) == S_OK){
-        newDevice->generic.devcaps.dwFlags |= DIDC_FORCEFEEDBACK;
-
-        hr = FFDeviceGetForceFeedbackCapabilities(newDevice->ff, &ffcaps);
-        if(SUCCEEDED(hr)){
-            TRACE("FF Capabilities:\n");
-            TRACE("\tsupportedEffects: 0x%x\n", (unsigned int)ffcaps.supportedEffects);
-            TRACE("\temulatedEffects: 0x%x\n", (unsigned int)ffcaps.emulatedEffects);
-            TRACE("\tsubType: 0x%x\n", (unsigned int)ffcaps.subType);
-            TRACE("\tnumFfAxes: %u\n", (unsigned int)ffcaps.numFfAxes);
-            TRACE("\tffAxes: [");
-            for(i = 0; i < ffcaps.numFfAxes; ++i){
-                TRACE("%s", osx_ff_axis_name(ffcaps.ffAxes[i]));
-                if(i < ffcaps.numFfAxes - 1)
-                    TRACE(", ");
-            }
-            TRACE("]\n");
-            TRACE("\tstorageCapacity: %u\n", (unsigned int)ffcaps.storageCapacity);
-            TRACE("\tplaybackCapacity: %u\n", (unsigned int)ffcaps.playbackCapacity);
-        }
-
-        hr = FFDeviceSendForceFeedbackCommand(newDevice->ff, FFSFFC_RESET);
-        if(FAILED(hr))
-            WARN("FFDeviceSendForceFeedbackCommand(FFSFFC_RESET) failed: %08x\n", hr);
-
-        hr = FFDeviceSendForceFeedbackCommand(newDevice->ff, FFSFFC_SETACTUATORSON);
-        if(FAILED(hr))
-            WARN("FFDeviceSendForceFeedbackCommand(FFSFFC_SETACTUATORSON) failed: %08x\n", hr);
-    }
-
-    memset(axis_map, 0, sizeof(axis_map));
-    get_osx_device_elements(newDevice, axis_map);
-
-    TRACE("%i axes %i buttons %i povs\n",newDevice->generic.devcaps.dwAxes,newDevice->generic.devcaps.dwButtons,newDevice->generic.devcaps.dwPOVs);
-
-    if (newDevice->generic.devcaps.dwButtons > 128)
-    {
-        WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->generic.devcaps.dwButtons);
-        newDevice->generic.devcaps.dwButtons = 128;
-    }
-
-    /* Create copy of default data format */
-    memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
-
-    df->dwNumObjs = newDevice->generic.devcaps.dwAxes + newDevice->generic.devcaps.dwPOVs + newDevice->generic.devcaps.dwButtons;
-    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED;
-
-    for (i = 0; i < newDevice->generic.devcaps.dwAxes; i++)
-    {
-        int wine_obj = -1;
-        BOOL has_ff  = FALSE;
-        switch (axis_map[i])
-        {
-            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_X):
-                wine_obj = 0;
-                has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_X);
-                break;
-            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Y):
-                wine_obj = 1;
-                has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_Y);
-                break;
-            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Z):
-                wine_obj = 2;
-                has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_Z);
-                break;
-            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Rx):
-            case MAKEUINT64(kHIDPage_Simulation, kHIDUsage_Sim_Accelerator):
-                wine_obj = 3;
-                has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_RX);
-                break;
-            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Ry):
-            case MAKEUINT64(kHIDPage_Simulation, kHIDUsage_Sim_Brake):
-                wine_obj = 4;
-                has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_RY);
-                break;
-            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Rz):
-                wine_obj = 5;
-                has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_RZ);
-                break;
-            case MAKEUINT64(kHIDPage_GenericDesktop, kHIDUsage_GD_Slider):
-                wine_obj = 6 + slider_count;
-                has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_SLIDER(slider_count));
-                slider_count++;
-                break;
-        }
-        if (wine_obj < 0 ) continue;
-
-        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
-        df->rgodf[idx].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
-        if(has_ff)
-            df->rgodf[idx].dwFlags |= DIDOI_FFACTUATOR;
-        ++idx;
-    }
-
-    for (i = 0; i < newDevice->generic.devcaps.dwPOVs; i++)
-    {
-        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 8], df->dwObjSize);
-        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_POV;
-    }
-
-    for (i = 0; i < newDevice->generic.devcaps.dwButtons; i++)
-    {
-        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize);
-        df->rgodf[idx  ].pguid = &GUID_Button;
-        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
-    }
-
-    /* initialize default properties */
-    get_osx_device_elements_props(newDevice);
-
-    newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
-    newDevice->generic.devcaps.dwFlags |= DIDC_ATTACHED;
-    if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
-        newDevice->generic.devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
-    else
-        newDevice->generic.devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
-    newDevice->generic.devcaps.dwFFSamplePeriod = 0;
-    newDevice->generic.devcaps.dwFFMinTimeResolution = 0;
-    newDevice->generic.devcaps.dwFirmwareRevision = 0;
-    newDevice->generic.devcaps.dwHardwareRevision = 0;
-    newDevice->generic.devcaps.dwFFDriverVersion = 0;
-
-    if (TRACE_ON(dinput)) {
-        TRACE("allocated device %p\n", newDevice);
-        _dump_DIDATAFORMAT(newDevice->generic.base.data_format.wine_df);
-        _dump_DIDEVCAPS(&newDevice->generic.devcaps);
-    }
-
-    *out = newDevice;
-    return DI_OK;
-
-FAILED:
-    hr = DIERR_OUTOFMEMORY;
-    if (newDevice->ff) FFReleaseDevice(newDevice->ff);
-    if (newDevice->elements) CFRelease(newDevice->elements);
-    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
-    HeapFree(GetProcessHeap(), 0, df);
-    release_DataFormat(&newDevice->generic.base.data_format);
-    HeapFree(GetProcessHeap(),0,newDevice->generic.name);
-    HeapFree(GetProcessHeap(),0,newDevice);
-    return hr;
-}
-
-/******************************************************************************
-  *     get_joystick_index : Get the joystick index from a given GUID
-  */
-static unsigned short get_joystick_index(REFGUID guid)
-{
-    GUID wine_joystick = DInput_Wine_OsX_Joystick_GUID;
-    GUID dev_guid = *guid;
-    GUID prod_guid = *guid;
-    IOHIDDeviceRef device;
-    int joystick_devices_count;
-    INT i;
-
-    wine_joystick.Data3 = 0;
-    dev_guid.Data3 = 0;
-
-    /* for the standard joystick GUID use index 0 */
-    if(IsEqualGUID(&GUID_Joystick,guid)) return 0;
-
-    /* for the wine joystick GUIDs use the index stored in Data3 */
-    if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3;
-
-    prod_guid.Data1 = 0;
-    if(IsEqualGUID(&dinput_pidvid_guid, &prod_guid))
-    {
-        joystick_devices_count = find_joystick_devices();
-        for(i = 0; i < joystick_devices_count; i++)
-        {
-            device = get_device_ref(i);
-            if(guid->Data1 == make_vid_pid(device))
-                return i;
-        }
-    }
-
-    return 0xffff;
-}
-
-static HRESULT joydev_create_device( IDirectInputImpl *dinput, REFGUID rguid, IDirectInputDevice8W **out )
-{
-    unsigned short index;
-    int joystick_devices_count;
-
-    TRACE( "%p %s %p\n", dinput, debugstr_guid( rguid ), out );
-    *out = NULL;
-
-    if ((joystick_devices_count = find_joystick_devices()) == 0)
-        return DIERR_DEVICENOTREG;
-
-    if ((index = get_joystick_index(rguid)) < 0xffff &&
-        joystick_devices_count && index < joystick_devices_count)
-    {
-        JoystickImpl *This;
-        HRESULT hr;
-
-        if (FAILED(hr = alloc_device( rguid, dinput, &This, index ))) return hr;
-
-        TRACE( "Created a Joystick device (%p)\n", This );
-
-        *out = &This->generic.base.IDirectInputDevice8W_iface;
-        return hr;
-    }
-
-    return DIERR_DEVICENOTREG;
-}
-
-static HRESULT WINAPI JoystickWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph);
-    _dump_DIPROPHEADER(pdiph);
-
-    if (!IS_DIPROP(rguid)) return DI_OK;
-
-    switch (LOWORD(rguid)) {
-    case (DWORD_PTR) DIPROP_GUIDANDPATH:
-    {
-        static const WCHAR formatW[] = {'\\','\\','?','\\','h','i','d','#','v','i','d','_','%','0','4','x','&',
-                                        'p','i','d','_','%','0','4','x','&','%','s','_','%','i',0};
-        static const WCHAR miW[] = {'m','i',0};
-        static const WCHAR igW[] = {'i','g',0};
-
-        BOOL is_gamepad;
-        IOHIDDeviceRef device = get_device_ref(This->id);
-        LPDIPROPGUIDANDPATH pd = (LPDIPROPGUIDANDPATH)pdiph;
-        WORD vid = get_device_property_long(device, CFSTR(kIOHIDVendorIDKey));
-        WORD pid = get_device_property_long(device, CFSTR(kIOHIDProductIDKey));
-
-        if (!pid || !vid)
-            return DIERR_UNSUPPORTED;
-
-        is_gamepad = is_xinput_device(&This->generic.devcaps, vid, pid);
-        pd->guidClass = GUID_DEVCLASS_HIDCLASS;
-        sprintfW(pd->wszPath, formatW, vid, pid, is_gamepad ? igW : miW, This->id);
-
-        TRACE("DIPROP_GUIDANDPATH(%s, %s): returning fake path\n", debugstr_guid(&pd->guidClass), debugstr_w(pd->wszPath));
-        break;
-    }
-
-    default:
-        return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph);
-    }
-
-    return DI_OK;
-}
-
-static HRESULT osx_set_autocenter(JoystickImpl *This,
-        const DIPROPDWORD *header)
-{
-    UInt32 v;
-    HRESULT hr;
-    if(!This->ff)
-        return DIERR_UNSUPPORTED;
-    v = header->dwData;
-    hr = osx_to_win32_hresult(FFDeviceSetForceFeedbackProperty(This->ff, FFPROP_AUTOCENTER, &v));
-    TRACE("returning: %08x\n", hr);
-    return hr;
-}
-
-static HRESULT osx_set_ffgain(JoystickImpl *This, const DIPROPDWORD *header)
-{
-    UInt32 v;
-    HRESULT hr;
-    if(!This->ff)
-        return DIERR_UNSUPPORTED;
-    v = header->dwData;
-    hr = osx_to_win32_hresult(FFDeviceSetForceFeedbackProperty(This->ff, FFPROP_FFGAIN, &v));
-    TRACE("returning: %08x\n", hr);
-    return hr;
-}
-
-static HRESULT WINAPI JoystickWImpl_SetProperty(IDirectInputDevice8W *iface,
-        const GUID *prop, const DIPROPHEADER *header)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("%p %s %p\n", This, debugstr_guid(prop), header);
-
-    switch(LOWORD(prop))
-    {
-    case (DWORD_PTR)DIPROP_AUTOCENTER:
-        return osx_set_autocenter(This, (const DIPROPDWORD *)header);
-    case (DWORD_PTR)DIPROP_FFGAIN:
-        return osx_set_ffgain(This, (const DIPROPDWORD *)header);
-    }
-
-    return JoystickWGenericImpl_SetProperty(iface, prop, header);
-}
-
-static CFUUIDRef effect_win_to_mac(const GUID *effect)
-{
-#define DO_MAP(X) \
-    if(IsEqualGUID(&GUID_##X, effect)) \
-        return kFFEffectType_##X##_ID;
-    DO_MAP(ConstantForce)
-    DO_MAP(RampForce)
-    DO_MAP(Square)
-    DO_MAP(Sine)
-    DO_MAP(Triangle)
-    DO_MAP(SawtoothUp)
-    DO_MAP(SawtoothDown)
-    DO_MAP(Spring)
-    DO_MAP(Damper)
-    DO_MAP(Inertia)
-    DO_MAP(Friction)
-    DO_MAP(CustomForce)
-#undef DO_MAP
-    WARN("Unknown effect GUID! %s\n", debugstr_guid(effect));
-    return 0;
-}
-
-static HRESULT WINAPI JoystickWImpl_CreateEffect(IDirectInputDevice8W *iface,
-        const GUID *type, const DIEFFECT *params, IDirectInputEffect **out,
-        IUnknown *outer)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-    EffectImpl *effect;
-    HRESULT hr;
-
-    TRACE("(%p)->(%s %p %p %p)\n", This, debugstr_guid(type), params, out, outer);
-    dump_DIEFFECT(params, type, 0);
-
-    if(!This->ff){
-        TRACE("No force feedback support\n");
-        *out = NULL;
-        return DIERR_UNSUPPORTED;
-    }
-
-    if(outer)
-        WARN("aggregation not implemented\n");
-
-    effect = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
-    effect->IDirectInputEffect_iface.lpVtbl = &EffectVtbl;
-    effect->ref = 1;
-    effect->guid = *type;
-    effect->device = This;
-
-    /* Mac's FFEFFECT and Win's DIEFFECT are binary identical. */
-    hr = osx_to_win32_hresult(FFDeviceCreateEffect(This->ff,
-                effect_win_to_mac(type), (FFEFFECT*)params, &effect->effect));
-    if(FAILED(hr)){
-        WARN("FFDeviceCreateEffect failed: %08x\n", hr);
-        HeapFree(GetProcessHeap(), 0, effect);
-        return hr;
-    }
-
-    list_add_tail(&This->effects, &effect->entry);
-    *out = &effect->IDirectInputEffect_iface;
-
-    TRACE("allocated effect: %p\n", effect);
-
-    return S_OK;
-}
-
-static HRESULT WINAPI JoystickWImpl_SendForceFeedbackCommand(IDirectInputDevice8W *iface,
-        DWORD flags)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-    HRESULT hr;
-
-    TRACE("%p 0x%x\n", This, flags);
-
-    if(!This->ff)
-        return DI_NOEFFECT;
-
-    hr = osx_to_win32_hresult(FFDeviceSendForceFeedbackCommand(This->ff, flags));
-    if(FAILED(hr)){
-        WARN("FFDeviceSendForceFeedbackCommand failed: %08x\n", hr);
-        return hr;
-    }
-
-    return S_OK;
-}
-
-const struct dinput_device joystick_osx_device = {
-  "Wine OS X joystick driver",
-  joydev_enum_device,
-  joydev_create_device
-};
-
-static const IDirectInputDevice8WVtbl JoystickWvt =
-{
-    IDirectInputDevice2WImpl_QueryInterface,
-    IDirectInputDevice2WImpl_AddRef,
-    JoystickWGenericImpl_Release,
-    JoystickWGenericImpl_GetCapabilities,
-    IDirectInputDevice2WImpl_EnumObjects,
-    JoystickWImpl_GetProperty,
-    JoystickWImpl_SetProperty,
-    IDirectInputDevice2WImpl_Acquire,
-    IDirectInputDevice2WImpl_Unacquire,
-    JoystickWGenericImpl_GetDeviceState,
-    IDirectInputDevice2WImpl_GetDeviceData,
-    IDirectInputDevice2WImpl_SetDataFormat,
-    IDirectInputDevice2WImpl_SetEventNotification,
-    IDirectInputDevice2WImpl_SetCooperativeLevel,
-    JoystickWGenericImpl_GetObjectInfo,
-    JoystickWGenericImpl_GetDeviceInfo,
-    IDirectInputDevice2WImpl_RunControlPanel,
-    IDirectInputDevice2WImpl_Initialize,
-    JoystickWImpl_CreateEffect,
-    IDirectInputDevice2WImpl_EnumEffects,
-    IDirectInputDevice2WImpl_GetEffectInfo,
-    IDirectInputDevice2WImpl_GetForceFeedbackState,
-    JoystickWImpl_SendForceFeedbackCommand,
-    IDirectInputDevice2WImpl_EnumCreatedEffectObjects,
-    IDirectInputDevice2WImpl_Escape,
-    JoystickWGenericImpl_Poll,
-    IDirectInputDevice2WImpl_SendDeviceData,
-    IDirectInputDevice7WImpl_EnumEffectsInFile,
-    IDirectInputDevice7WImpl_WriteEffectToFile,
-    JoystickWGenericImpl_BuildActionMap,
-    JoystickWGenericImpl_SetActionMap,
-    IDirectInputDevice8WImpl_GetImageInfo
-};
-
-static HRESULT WINAPI effect_QueryInterface(IDirectInputEffect *iface,
-        const GUID *guid, void **out)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-
-    TRACE("%p %s %p\n", This, debugstr_guid(guid), out);
-
-    if(IsEqualIID(guid, &IID_IUnknown) || IsEqualIID(guid, &IID_IDirectInputEffect)){
-        *out = iface;
-        IDirectInputEffect_AddRef(iface);
-        return S_OK;
-    }
-
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI effect_AddRef(IDirectInputEffect *iface)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    ULONG ref = InterlockedIncrement(&This->ref);
-    TRACE("%p, ref is now: %u\n", This, ref);
-    return ref;
-}
-
-static ULONG WINAPI effect_Release(IDirectInputEffect *iface)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    ULONG ref = InterlockedDecrement(&This->ref);
-    TRACE("%p, ref is now: %u\n", This, ref);
-
-    if(!ref){
-        list_remove(&This->entry);
-        FFDeviceReleaseEffect(This->device->ff, This->effect);
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-
-    return ref;
-}
-
-static HRESULT WINAPI effect_Initialize(IDirectInputEffect *iface, HINSTANCE hinst,
-        DWORD version, const GUID *guid)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p %p 0x%x, %s\n", This, hinst, version, debugstr_guid(guid));
-    return S_OK;
-}
-
-static HRESULT WINAPI effect_GetEffectGuid(IDirectInputEffect *iface, GUID *out)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p %p\n", This, out);
-    *out = This->guid;
-    return S_OK;
-}
-
-static HRESULT WINAPI effect_GetParameters(IDirectInputEffect *iface,
-        DIEFFECT *effect, DWORD flags)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p %p 0x%x\n", This, effect, flags);
-    return osx_to_win32_hresult(FFEffectGetParameters(This->effect, (FFEFFECT*)effect, flags));
-}
-
-static HRESULT WINAPI effect_SetParameters(IDirectInputEffect *iface,
-        const DIEFFECT *effect, DWORD flags)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p %p 0x%x\n", This, effect, flags);
-    dump_DIEFFECT(effect, &This->guid, flags);
-    return osx_to_win32_hresult(FFEffectSetParameters(This->effect, (FFEFFECT*)effect, flags));
-}
-
-static HRESULT WINAPI effect_Start(IDirectInputEffect *iface, DWORD iterations,
-        DWORD flags)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p 0x%x 0x%x\n", This, iterations, flags);
-    return osx_to_win32_hresult(FFEffectStart(This->effect, iterations, flags));
-}
-
-static HRESULT WINAPI effect_Stop(IDirectInputEffect *iface)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p\n", This);
-    return osx_to_win32_hresult(FFEffectStop(This->effect));
-}
-
-static HRESULT WINAPI effect_GetEffectStatus(IDirectInputEffect *iface, DWORD *flags)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p %p\n", This, flags);
-    return osx_to_win32_hresult(FFEffectGetEffectStatus(This->effect, (UInt32*)flags));
-}
-
-static HRESULT WINAPI effect_Download(IDirectInputEffect *iface)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p\n", This);
-    return osx_to_win32_hresult(FFEffectDownload(This->effect));
-}
-
-static HRESULT WINAPI effect_Unload(IDirectInputEffect *iface)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p\n", This);
-    return osx_to_win32_hresult(FFEffectUnload(This->effect));
-}
-
-static HRESULT WINAPI effect_Escape(IDirectInputEffect *iface, DIEFFESCAPE *escape)
-{
-    EffectImpl *This = impl_from_IDirectInputEffect(iface);
-    TRACE("%p %p\n", This, escape);
-    return osx_to_win32_hresult(FFEffectEscape(This->effect, (FFEFFESCAPE*)escape));
-}
-
-static const IDirectInputEffectVtbl EffectVtbl = {
-    effect_QueryInterface,
-    effect_AddRef,
-    effect_Release,
-    effect_Initialize,
-    effect_GetEffectGuid,
-    effect_GetParameters,
-    effect_SetParameters,
-    effect_Start,
-    effect_Stop,
-    effect_GetEffectStatus,
-    effect_Download,
-    effect_Unload,
-    effect_Escape
-};
-
-#else /* HAVE_IOHIDMANAGERCREATE */
-
-const struct dinput_device joystick_osx_device = {
-  "Wine OS X joystick driver",
-  NULL,
-  NULL,
-};
-
-#endif /* HAVE_IOHIDMANAGERCREATE */
diff --git a/dlls/dinput/joystick_private.h b/dlls/dinput/joystick_private.h
deleted file mode 100644
index 32265edef03..00000000000
--- a/dlls/dinput/joystick_private.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2009, Aric Stewart, CodeWeavers
- *
- * 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
- */
-
-#ifndef __WINE_DLLS_DINPUT_JOYSTICK_PRIVATE_H
-#define __WINE_DLLS_DINPUT_JOYSTICK_PRIVATE_H
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "dinput.h"
-#include "wine/list.h"
-#include "wine/unicode.h"
-#include "dinput_private.h"
-#include "device_private.h"
-
-/* Number of objects in the default data format */
-#define MAX_PROPS 164
-struct JoystickGenericImpl;
-
-typedef void joy_polldev_handler( IDirectInputDevice8W *iface );
-
-typedef struct JoystickGenericImpl
-{
-    struct IDirectInputDeviceImpl base;
-
-    ObjProps    props[MAX_PROPS];
-    DIDEVCAPS   devcaps;
-    DIJOYSTATE2 js;     /* wine data */
-    GUID        guidProduct;
-    GUID        guidInstance;
-    char        *name;
-    int         device_axis_count;      /* Total number of axes in the device */
-    int        *axis_map;               /* User axes remapping */
-    LONG        deadzone;               /* Default dead-zone */
-
-    joy_polldev_handler *joy_polldev;
-} JoystickGenericImpl;
-
-LONG joystick_map_axis(ObjProps *props, int val) DECLSPEC_HIDDEN;
-HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_map) DECLSPEC_HIDDEN;
-
-DWORD joystick_map_pov(const POINTL *p) DECLSPEC_HIDDEN;
-
-BOOL device_disabled_registry(const char* name) DECLSPEC_HIDDEN;
-BOOL device_instance_is_disabled( DIDEVICEINSTANCEW *instance, BOOL *override ) DECLSPEC_HIDDEN;
-
-ULONG WINAPI JoystickWGenericImpl_Release(LPDIRECTINPUTDEVICE8W iface);
-
-HRESULT WINAPI JoystickWGenericImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
-        LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) DECLSPEC_HIDDEN;
-
-HRESULT WINAPI JoystickWGenericImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph) DECLSPEC_HIDDEN;
-
-HRESULT WINAPI JoystickWGenericImpl_GetCapabilities(LPDIRECTINPUTDEVICE8W iface, LPDIDEVCAPS lpDIDevCaps) DECLSPEC_HIDDEN;
-
-void _dump_DIDEVCAPS(const DIDEVCAPS *lpDIDevCaps) DECLSPEC_HIDDEN;
-
-HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIPROPHEADER ph) DECLSPEC_HIDDEN;
-
-HRESULT WINAPI JoystickWGenericImpl_GetDeviceInfo( LPDIRECTINPUTDEVICE8W iface,
-    LPDIDEVICEINSTANCEW pdidi) DECLSPEC_HIDDEN;
-
-HRESULT WINAPI JoystickWGenericImpl_Poll(LPDIRECTINPUTDEVICE8W iface) DECLSPEC_HIDDEN;
-
-HRESULT WINAPI JoystickWGenericImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W iface, DWORD len, LPVOID ptr) DECLSPEC_HIDDEN;
-
-HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags) DECLSPEC_HIDDEN;
-
-HRESULT WINAPI JoystickWGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags) DECLSPEC_HIDDEN;
-
-DWORD typeFromGUID(REFGUID guid) DECLSPEC_HIDDEN;
-void dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid, DWORD dwFlags) DECLSPEC_HIDDEN;
-BOOL is_xinput_device(const DIDEVCAPS *devcaps, WORD vid, WORD pid) DECLSPEC_HIDDEN;
-
-#endif /* __WINE_DLLS_DINPUT_JOYSTICK_PRIVATE_H */
diff --git a/dlls/dinput8/Makefile.in b/dlls/dinput8/Makefile.in
index 23017cb5983..1d3574aa1a0 100644
--- a/dlls/dinput8/Makefile.in
+++ b/dlls/dinput8/Makefile.in
@@ -2,7 +2,6 @@ MODULE    = dinput8.dll
 IMPORTLIB = dinput8
 IMPORTS   = dinput8 dxguid uuid comctl32 ole32 user32 advapi32 hid setupapi
 EXTRADEFS = -DDIRECTINPUT_VERSION=0x0800
-EXTRALIBS = $(IOKIT_LIBS) $(FORCEFEEDBACK_LIBS)
 PARENTSRC = ../dinput
 
 EXTRADLLFLAGS = -mcygwin
@@ -13,12 +12,7 @@ C_SRCS = \
 	data_formats.c \
 	device.c \
 	dinput_main.c \
-	effect_linuxinput.c \
-	joystick.c \
 	joystick_hid.c \
-	joystick_linux.c \
-	joystick_linuxinput.c \
-	joystick_osx.c \
 	keyboard.c \
 	mouse.c
 
-- 
2.33.0




More information about the wine-devel mailing list