[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