mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Sync to Wine-20050930:
Jakob Eriksson <jakov@vmlinux.org> - Get rid of HeapAlloc casts. Robert Reif <reif@earthlink.net> - Added keyboard data format. - Fix joystick crash when a button guid is specified in the data format. Add some parameter checking. - Pass around real version and do correct thing based on it. Change cooperative level to pass on windows. - Fix SetProperty error returned. Add EnumDevice joystick version check. Test multiple versions. - Added dinput tests. - Effect objects are not supported yet so don't crash when trying to enumerate them. Raphael Junqueira <fenix@club-internet.fr> - use WINE_DINPUT_KEYBOARD_MAX_KEYS instead hard-coded 256 value - better use of critical section - some cleanup to better understand code paths - logic correction on SetWindowsHookExA/UnhookWindowsHookEx on keyboard. Alexandre Julliard <julliard@winehq.org> - Build a static list of devices instead of relying on ELF constructors. Gerald Pfeifer <gerald@pfeifer.com> - Fix compilation of the case without proper Linux joystick support. James Dean Anderson <petr@pantek.org> - Report an error if trying to get data from an unacquired mouse. Lionel Ulmer <lionel.ulmer@free.fr> - more pretty print for the types flag - more Windows-aligned check for object instances - Windows reports 0x80 on pressed buttons not 0xFF - trace the events reported to the application - do not flush the buffer when the application only wants to peek the number of elements in the queue - trace the GetDeviceState values before they are reset Alexandre Julliard <julliard@winehq.org> - Added rules for building import libraries in the individual dll makefiles, and added support for building a .def.a static import library too. - Added rules to build import libraries in the individual dll makefiles. Generate import libraries with the right name right away instead of using an intermediate .spec.def file. - Moved config parameters to HKCU\Software\Wine\DirectInput. - Added magic comments to all Wine-specific registry accesses to make them easier to grep. - Sort entry points alphabetically. - Removed some unused or redundant configure checks. A few cleanups in configure.ac. - Don't prefix the functions DllCanUnloadNow, DllGetClassObject and Dll(Un)RegisterServer with the dll name so that the compiler can check the prototypes. - Fixed some traces to use the right printf format and avoid typecasts. - Use a more portable scheme for storing the name of a critical section. - Use the COM macros instead of accessing lpVtbl directly. - We are no longer generating .dbg.c files. Marcus Meissner <marcus@jet.franken.de> - The last argument to MultiByteToWideChar is wide character count and not the buffer size in bytes. Fixed all places where it was wrong. - Fixed 3 memset()s which used the wrong size (too large). Dmitry Timoshkov <dmitry@codeweavers.com> - Make more of the OLE interface vtables const. Daniel Remenak <dtremenak@gmail.com> - Added a linux input system force feedback effect implementation. - Allow the creation of an FF effect while the joystick is not acquired. - Failing to download an effect after setting parameters is not a fatal error. - Allow enumeration of objects when the device is not yet acquired. - Flag FF-capable axes during enumeration. - Protect FF_STATUS usage to avoid compile errors on machines with old linux/input.h. - Implement EnumEffects, CreateEffect, EnumCreatedEffects, SendForceFeedbackCommand, and GetForceFeedbackStatus for linux input joysticks. - Correct dinput handling of sliders and non-zero-based axes through the linux input system. - Correctly enumerate evdev joysticks when enumeration is restricted with DIEDFL_FORCEFEEDBACK. - Detect force-feedback-capable linux event device joysticks and return DIDC_FORCEFEEDBACK when queried for capabilities. Mike McCormack <mike@codeweavers.com> - Interlocked LONG* gcc warning fixes. - gcc 4.0 warning fixes. - gcc 4.0 warning fixes for Interlocked* functions. - Fix warnings for no force feedback case. Stefan Huehner <stefan@huehner.org> - Fix some more -Wmissing-declarations warnings. Vincent Béron <vberon@mecano.gme.usherb.ca> - Use proper ifdefs around unistd.h. svn path=/trunk/; revision=18361
This commit is contained in:
parent
d2af8e74ef
commit
2ffd7b7d5a
13 changed files with 1570 additions and 164 deletions
|
@ -464,7 +464,7 @@ HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
|
|||
LPDIRECTINPUTDEVICE8A iface,HWND hwnd,DWORD dwflags
|
||||
) {
|
||||
IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface;
|
||||
TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
|
||||
TRACE("(this=%p,%p,0x%08lx)\n",This,hwnd,dwflags);
|
||||
if (TRACE_ON(dinput)) {
|
||||
TRACE(" cooperative level : ");
|
||||
_dump_cooperativelevel_DI(dwflags);
|
||||
|
@ -476,7 +476,7 @@ HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
|
|||
LPDIRECTINPUTDEVICE8A iface,HANDLE hnd
|
||||
) {
|
||||
IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface;
|
||||
FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
|
||||
FIXME("(this=%p,%p): stub\n",This,hnd);
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl;
|
||||
struct IDirectInputDevice2AImpl
|
||||
{
|
||||
IDirectInputDevice2AVtbl *lpVtbl;
|
||||
DWORD ref;
|
||||
const IDirectInputDevice2AVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
GUID guid;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@ stdcall DirectInputCreateA(long long ptr ptr)
|
||||
@ stdcall DirectInputCreateW(long long ptr ptr)
|
||||
@ stdcall DirectInputCreateEx(long long ptr ptr ptr)
|
||||
@ stdcall -private DllCanUnloadNow() DINPUT_DllCanUnloadNow
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr) DINPUT_DllGetClassObject
|
||||
@ stdcall -private DllRegisterServer() DINPUT_DllRegisterServer
|
||||
@ stdcall -private DllUnregisterServer() DINPUT_DllUnregisterServer
|
||||
@ stdcall DirectInputCreateA(long long ptr ptr)
|
||||
@ stdcall DirectInputCreateEx(long long ptr ptr ptr)
|
||||
@ stdcall DirectInputCreateW(long long ptr ptr)
|
||||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stdcall -private DllRegisterServer()
|
||||
@ stdcall -private DllUnregisterServer()
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<file>data_formats.c</file>
|
||||
<file>device.c</file>
|
||||
<file>dinput_main.c</file>
|
||||
<file>effect_linuxinput.c</file>
|
||||
<file>joystick_linux.c</file>
|
||||
<file>joystick_linuxinput.c</file>
|
||||
<file>keyboard.c</file>
|
||||
|
|
|
@ -46,10 +46,10 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
|
||||
|
||||
static IDirectInput7AVtbl ddi7avt;
|
||||
static IDirectInput7WVtbl ddi7wvt;
|
||||
static IDirectInput8AVtbl ddi8avt;
|
||||
static IDirectInput8WVtbl ddi8wvt;
|
||||
static const IDirectInput7AVtbl ddi7avt;
|
||||
static const IDirectInput7WVtbl ddi7wvt;
|
||||
static const IDirectInput8AVtbl ddi8avt;
|
||||
static const IDirectInput8WVtbl ddi8wvt;
|
||||
|
||||
static const struct dinput_device *dinput_devices[] =
|
||||
{
|
||||
|
@ -86,7 +86,7 @@ HRESULT WINAPI DirectInputCreateEx(
|
|||
{
|
||||
IDirectInputImpl* This;
|
||||
|
||||
TRACE("(0x%08lx,%04lx,%s,%p,%p)\n", (DWORD)hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter);
|
||||
TRACE("(%p,%04lx,%s,%p,%p)\n", hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter);
|
||||
|
||||
if (IsEqualGUID(&IID_IDirectInputA,riid) ||
|
||||
IsEqualGUID(&IID_IDirectInput2A,riid) ||
|
||||
|
@ -384,7 +384,7 @@ static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUT7A iface,
|
|||
HWND hwndOwner,
|
||||
DWORD dwFlags) {
|
||||
IDirectInputImpl *This = (IDirectInputImpl *)iface;
|
||||
FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
|
||||
FIXME("(%p)->(%p,%08lx): stub\n",This, hwndOwner, dwFlags);
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
@ -535,7 +535,7 @@ static HRESULT WINAPI IDirectInput8WImpl_ConfigureDevices(
|
|||
# define XCAST(fun) (void*)
|
||||
#endif
|
||||
|
||||
static IDirectInput7AVtbl ddi7avt = {
|
||||
static const IDirectInput7AVtbl ddi7avt = {
|
||||
XCAST(QueryInterface)IDirectInputAImpl_QueryInterface,
|
||||
XCAST(AddRef)IDirectInputAImpl_AddRef,
|
||||
XCAST(Release)IDirectInputAImpl_Release,
|
||||
|
@ -555,7 +555,7 @@ static IDirectInput7AVtbl ddi7avt = {
|
|||
# define XCAST(fun) (void*)
|
||||
#endif
|
||||
|
||||
static IDirectInput7WVtbl ddi7wvt = {
|
||||
static const IDirectInput7WVtbl ddi7wvt = {
|
||||
XCAST(QueryInterface)IDirectInputWImpl_QueryInterface,
|
||||
XCAST(AddRef)IDirectInputAImpl_AddRef,
|
||||
XCAST(Release)IDirectInputAImpl_Release,
|
||||
|
@ -575,7 +575,7 @@ static IDirectInput7WVtbl ddi7wvt = {
|
|||
# define XCAST(fun) (void*)
|
||||
#endif
|
||||
|
||||
static IDirectInput8AVtbl ddi8avt = {
|
||||
static const IDirectInput8AVtbl ddi8avt = {
|
||||
XCAST(QueryInterface)IDirectInput8AImpl_QueryInterface,
|
||||
XCAST(AddRef)IDirectInputAImpl_AddRef,
|
||||
XCAST(Release)IDirectInputAImpl_Release,
|
||||
|
@ -595,7 +595,7 @@ static IDirectInput8AVtbl ddi8avt = {
|
|||
#else
|
||||
# define XCAST(fun) (void*)
|
||||
#endif
|
||||
static IDirectInput8WVtbl ddi8wvt = {
|
||||
static const IDirectInput8WVtbl ddi8wvt = {
|
||||
XCAST(QueryInterface)IDirectInput8WImpl_QueryInterface,
|
||||
XCAST(AddRef)IDirectInputAImpl_AddRef,
|
||||
XCAST(Release)IDirectInputAImpl_Release,
|
||||
|
@ -616,8 +616,8 @@ static IDirectInput8WVtbl ddi8wvt = {
|
|||
typedef struct
|
||||
{
|
||||
/* IUnknown fields */
|
||||
IClassFactoryVtbl *lpVtbl;
|
||||
DWORD ref;
|
||||
const IClassFactoryVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
} IClassFactoryImpl;
|
||||
|
||||
static HRESULT WINAPI DICF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
|
||||
|
@ -666,7 +666,7 @@ static HRESULT WINAPI DICF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static IClassFactoryVtbl DICF_Vtbl = {
|
||||
static const IClassFactoryVtbl DICF_Vtbl = {
|
||||
DICF_QueryInterface,
|
||||
DICF_AddRef,
|
||||
DICF_Release,
|
||||
|
@ -678,7 +678,7 @@ static IClassFactoryImpl DINPUT_CF = {&DICF_Vtbl, 1 };
|
|||
/***********************************************************************
|
||||
* DllCanUnloadNow (DINPUT.@)
|
||||
*/
|
||||
HRESULT WINAPI DINPUT_DllCanUnloadNow(void)
|
||||
HRESULT WINAPI DllCanUnloadNow(void)
|
||||
{
|
||||
FIXME("(void): stub\n");
|
||||
|
||||
|
@ -688,8 +688,7 @@ HRESULT WINAPI DINPUT_DllCanUnloadNow(void)
|
|||
/***********************************************************************
|
||||
* DllGetClassObject (DINPUT.@)
|
||||
*/
|
||||
HRESULT WINAPI DINPUT_DllGetClassObject(REFCLSID rclsid, REFIID riid,
|
||||
LPVOID *ppv)
|
||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
||||
if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
typedef struct IDirectInputImpl IDirectInputImpl;
|
||||
struct IDirectInputImpl
|
||||
{
|
||||
LPVOID lpVtbl;
|
||||
DWORD ref;
|
||||
const void *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* Used to have an unique sequence number for all the events */
|
||||
DWORD evsequence;
|
||||
|
|
927
reactos/lib/dinput/effect_linuxinput.c
Normal file
927
reactos/lib/dinput/effect_linuxinput.c
Normal file
|
@ -0,0 +1,927 @@
|
|||
/* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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>
|
||||
#endif
|
||||
#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"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
|
||||
|
||||
static const IDirectInputEffectVtbl LinuxInputEffectVtbl;
|
||||
typedef struct LinuxInputEffectImpl LinuxInputEffectImpl;
|
||||
struct LinuxInputEffectImpl
|
||||
{
|
||||
const void *lpVtbl;
|
||||
LONG ref;
|
||||
GUID guid;
|
||||
|
||||
/* Effect data */
|
||||
struct ff_effect effect;
|
||||
|
||||
/* Parent device */
|
||||
int* fd;
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* DirectInputEffect Functional Helper
|
||||
*/
|
||||
|
||||
static 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* DirectInputEffect debug helpers
|
||||
*/
|
||||
|
||||
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 < (sizeof(flags) / sizeof(flags[0])); i++)
|
||||
if (flags[i].mask & dwFlags)
|
||||
DPRINTF("%s ", flags[i].name);
|
||||
DPRINTF("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void _dump_DIENVELOPE(LPDIENVELOPE env)
|
||||
{
|
||||
if (env->dwSize != sizeof(DIENVELOPE)) {
|
||||
WARN("Non-standard DIENVELOPE structure size (%ld instead of %d).\n",
|
||||
env->dwSize, sizeof(DIENVELOPE));
|
||||
}
|
||||
TRACE("Envelope has attack (level: %ld time: %ld), fade (level: %ld time: %ld)\n",
|
||||
env->dwAttackLevel, env->dwAttackTime, env->dwFadeLevel, env->dwFadeTime);
|
||||
}
|
||||
|
||||
static void _dump_DICONSTANTFORCE(LPDICONSTANTFORCE frc)
|
||||
{
|
||||
TRACE("Constant force has magnitude %ld\n", frc->lMagnitude);
|
||||
}
|
||||
|
||||
static void _dump_DIPERIODIC(LPDIPERIODIC frc)
|
||||
{
|
||||
TRACE("Periodic force has magnitude %ld, offset %ld, phase %ld, period %ld\n",
|
||||
frc->dwMagnitude, frc->lOffset, frc->dwPhase, frc->dwPeriod);
|
||||
}
|
||||
|
||||
static void _dump_DIRAMPFORCE(LPDIRAMPFORCE frc)
|
||||
{
|
||||
TRACE("Ramp force has start %ld, end %ld\n",
|
||||
frc->lStart, frc->lEnd);
|
||||
}
|
||||
|
||||
static void _dump_DICONDITION(LPDICONDITION frc)
|
||||
{
|
||||
TRACE("Condition has offset %ld, pos/neg coefficients %ld and %ld, pos/neg saturations %ld and %ld, deadband %ld\n",
|
||||
frc->lOffset, frc->lPositiveCoefficient, frc->lNegativeCoefficient,
|
||||
frc->dwPositiveSaturation, frc->dwNegativeSaturation, frc->lDeadBand);
|
||||
}
|
||||
|
||||
static void _dump_DICUSTOMFORCE(LPDICUSTOMFORCE frc)
|
||||
{
|
||||
unsigned int i;
|
||||
TRACE("Custom force uses %ld channels, sample period %ld. Has %ld 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)) {
|
||||
DPRINTF("Custom force data (time aligned, axes in order):\n");
|
||||
for (i = 1; i <= frc->cSamples; ++i) {
|
||||
DPRINTF("%ld ", frc->rglForceData[i]);
|
||||
if (i % frc->cChannels == 0)
|
||||
DPRINTF("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid)
|
||||
{
|
||||
unsigned int i;
|
||||
DWORD type = _typeFromGUID(guid);
|
||||
|
||||
TRACE("Dumping DIEFFECT structure:\n");
|
||||
TRACE(" - dwSize: %ld\n", eff->dwSize);
|
||||
if ((eff->dwSize != sizeof(DIEFFECT)) && (eff->dwSize != sizeof(DIEFFECT_DX5))) {
|
||||
WARN("Non-standard DIEFFECT structure size (%ld instead of %d or %d).\n",
|
||||
eff->dwSize, sizeof(DIEFFECT), sizeof(DIEFFECT_DX5));
|
||||
}
|
||||
TRACE(" - dwFlags: %ld\n", eff->dwFlags);
|
||||
TRACE(" ");
|
||||
_dump_DIEFFECT_flags(eff->dwFlags);
|
||||
TRACE(" - dwDuration: %ld\n", eff->dwDuration);
|
||||
TRACE(" - dwGain: %ld\n", eff->dwGain);
|
||||
if ((eff->dwGain > 10000) || (eff->dwGain < 0))
|
||||
WARN("dwGain is out of range (0 - 10,000)\n");
|
||||
TRACE(" - dwTriggerButton: %ld\n", eff->dwTriggerButton);
|
||||
TRACE(" - dwTriggerRepeatInterval: %ld\n", eff->dwTriggerRepeatInterval);
|
||||
TRACE(" - cAxes: %ld\n", eff->cAxes);
|
||||
TRACE(" - rgdwAxes: %p\n", eff->rgdwAxes);
|
||||
if (TRACE_ON(dinput)) {
|
||||
TRACE(" ");
|
||||
for (i = 0; i < eff->cAxes; ++i)
|
||||
DPRINTF("%ld ", eff->rgdwAxes[i]);
|
||||
DPRINTF("\n");
|
||||
}
|
||||
TRACE(" - rglDirection: %p\n", eff->rglDirection);
|
||||
TRACE(" - lpEnvelope: %p\n", eff->lpEnvelope);
|
||||
TRACE(" - cbTypeSpecificParams: %ld\n", eff->cbTypeSpecificParams);
|
||||
TRACE(" - lpvTypeSpecificParams: %p\n", eff->lpvTypeSpecificParams);
|
||||
if (eff->dwSize > sizeof(DIEFFECT_DX5))
|
||||
TRACE(" - dwStartDelay: %ld\n", eff->dwStartDelay);
|
||||
if (eff->lpEnvelope != NULL)
|
||||
_dump_DIENVELOPE(eff->lpEnvelope);
|
||||
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 {
|
||||
_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 {
|
||||
_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 {
|
||||
_dump_DIRAMPFORCE(eff->lpvTypeSpecificParams);
|
||||
}
|
||||
} else if (type == DIEFT_CONDITION) {
|
||||
if (eff->cbTypeSpecificParams != sizeof(DICONDITION)) {
|
||||
WARN("Effect claims to be a condition but the type-specific params are the wrong size!\n");
|
||||
} else {
|
||||
_dump_DICONDITION(eff->lpvTypeSpecificParams);
|
||||
}
|
||||
} 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 {
|
||||
_dump_DICUSTOMFORCE(eff->lpvTypeSpecificParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* LinuxInputEffectImpl
|
||||
*/
|
||||
|
||||
static ULONG WINAPI LinuxInputEffectImpl_AddRef(
|
||||
LPDIRECTINPUTEFFECT iface)
|
||||
{
|
||||
LinuxInputEffectImpl *This = (LinuxInputEffectImpl *)iface;
|
||||
return InterlockedIncrement(&(This->ref));
|
||||
}
|
||||
|
||||
static HRESULT WINAPI LinuxInputEffectImpl_Download(
|
||||
LPDIRECTINPUTEFFECT iface)
|
||||
{
|
||||
LinuxInputEffectImpl *This = (LinuxInputEffectImpl *)iface;
|
||||
|
||||
TRACE("(this=%p)\n", This);
|
||||
|
||||
if (ioctl(*(This->fd), EVIOCSFF, &This->effect) == -1) {
|
||||
if (errno == ENOMEM) {
|
||||
return DIERR_DEVICEFULL;
|
||||
} else {
|
||||
FIXME("Could not upload effect. Assuming a disconnected device.\n");
|
||||
return DIERR_INPUTLOST;
|
||||
}
|
||||
}
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
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 = (LinuxInputEffectImpl*)iface;
|
||||
|
||||
TRACE("(this=%p,%p)\n", This, pguid);
|
||||
|
||||
pguid = &This->guid;
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI LinuxInputEffectImpl_GetEffectStatus(
|
||||
LPDIRECTINPUTEFFECT iface,
|
||||
LPDWORD pdwFlags)
|
||||
{
|
||||
TRACE("(this=%p,%p)\n", iface, pdwFlags);
|
||||
|
||||
/* 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 = (LinuxInputEffectImpl *)iface;
|
||||
TRACE("(this=%p,%p,%ld)\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) {
|
||||
peff->rglDirection[0] = (long)(sin(M_PI * 3 * This->effect.direction / 0x7FFF) * 1000);
|
||||
peff->rglDirection[1] = (long)(cos(M_PI * 3 * This->effect.direction / 0x7FFF) * 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) {
|
||||
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) {
|
||||
/* the linux input ff driver apparently has no support
|
||||
* for setting the device's gain. */
|
||||
peff->dwGain = DI_FFNOMINALMAX;
|
||||
}
|
||||
|
||||
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->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) {
|
||||
int 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 = (LPDIPERIODIC)(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 = (LPDICONSTANTFORCE)(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 = (LPDICONDITION)(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 = (LPDIRAMPFORCE)(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,%ld,%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 = (LinuxInputEffectImpl*)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 = (LinuxInputEffectImpl*)iface;
|
||||
|
||||
TRACE("(this=%p,%ld,%ld)\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 = dwIterations;
|
||||
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 = (LinuxInputEffectImpl*)iface;
|
||||
DWORD type = _typeFromGUID(&This->guid);
|
||||
HRESULT retval = DI_OK;
|
||||
|
||||
TRACE("(this=%p,%p,%ld)\n", This, peff, dwFlags);
|
||||
|
||||
_dump_DIEFFECT(peff, &This->guid);
|
||||
|
||||
if ((dwFlags & !DIEP_NORESTART & !DIEP_NODOWNLOAD & !DIEP_START) == 0) {
|
||||
/* set everything */
|
||||
dwFlags = DIEP_AXES | DIEP_DIRECTION | DIEP_DURATION | DIEP_ENVELOPE |
|
||||
DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_STARTDELAY | DIEP_TRIGGERBUTTON |
|
||||
DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS;
|
||||
}
|
||||
|
||||
if (dwFlags & DIEP_AXES) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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->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;
|
||||
}
|
||||
} else { /* two axes */
|
||||
if (peff->dwFlags & DIEFF_CARTESIAN) {
|
||||
/* avoid divide-by-zero */
|
||||
if (peff->rglDirection[1] == 0) {
|
||||
if (peff->rglDirection[0] >= 0)
|
||||
This->effect.direction = 0x4000;
|
||||
else if (peff->rglDirection[0] < 0)
|
||||
This->effect.direction = 0xC000;
|
||||
} else {
|
||||
This->effect.direction = (int)(atan(peff->rglDirection[0] / peff->rglDirection[1]) * 0x7FFF / (3 * 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 = (int)(((double)peff->rglDirection[0] - 90) / 35999) * 0x7FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dwFlags & DIEP_DURATION)
|
||||
This->effect.replay.length = peff->dwDuration / 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 (peff->lpEnvelope == NULL) {
|
||||
/* if this type had an envelope, reset it
|
||||
* note that length can never be zero, so we set it to something miniscule */
|
||||
if (env) {
|
||||
env->attack_length = 0x10;
|
||||
env->attack_level = 0x7FFF;
|
||||
env->fade_length = 0x10;
|
||||
env->fade_level = 0x7FFF;
|
||||
}
|
||||
} else {
|
||||
/* did we get passed an envelope for a type that doesn't even have one? */
|
||||
if (!env) return DIERR_INVALIDPARAM;
|
||||
/* copy the envelope */
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Gain and Sample Period settings are not supported by the linux
|
||||
* event system */
|
||||
if (dwFlags & DIEP_GAIN)
|
||||
TRACE("Gain requested but no gain functionality present.\n");
|
||||
|
||||
if (dwFlags & DIEP_SAMPLEPERIOD)
|
||||
TRACE("Sample period requested but no sample period functionality present.\n");
|
||||
|
||||
if (dwFlags & DIEP_STARTDELAY)
|
||||
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_INCOMPLETEEFFECT;
|
||||
if (type == DIEFT_PERIODIC) {
|
||||
LPCDIPERIODIC tsp;
|
||||
if (peff->cbTypeSpecificParams != sizeof(DIPERIODIC))
|
||||
return DIERR_INVALIDPARAM;
|
||||
tsp = (LPCDIPERIODIC)(peff->lpvTypeSpecificParams);
|
||||
This->effect.u.periodic.magnitude = (tsp->dwMagnitude / 10) * 32;
|
||||
This->effect.u.periodic.offset = (tsp->lOffset / 10) * 32;
|
||||
This->effect.u.periodic.phase = (tsp->dwPhase / 9) * 8; /* == (/ 36 * 32) */
|
||||
This->effect.u.periodic.period = tsp->dwPeriod / 1000;
|
||||
} else if (type == DIEFT_CONSTANTFORCE) {
|
||||
LPCDICONSTANTFORCE tsp;
|
||||
if (peff->cbTypeSpecificParams != sizeof(DICONSTANTFORCE))
|
||||
return DIERR_INVALIDPARAM;
|
||||
tsp = (LPCDICONSTANTFORCE)(peff->lpvTypeSpecificParams);
|
||||
This->effect.u.constant.level = (tsp->lMagnitude / 10) * 32;
|
||||
} else if (type == DIEFT_RAMPFORCE) {
|
||||
LPCDIRAMPFORCE tsp;
|
||||
if (peff->cbTypeSpecificParams != sizeof(DIRAMPFORCE))
|
||||
return DIERR_INVALIDPARAM;
|
||||
tsp = (LPCDIRAMPFORCE)(peff->lpvTypeSpecificParams);
|
||||
This->effect.u.ramp.start_level = (tsp->lStart / 10) * 32;
|
||||
This->effect.u.ramp.end_level = (tsp->lStart / 10) * 32;
|
||||
} else if (type == DIEFT_CONDITION) {
|
||||
LPCDICONDITION tsp = (LPCDICONDITION)(peff->lpvTypeSpecificParams);
|
||||
if (peff->cbTypeSpecificParams == sizeof(DICONDITION)) {
|
||||
/* One condition block. This needs to be rotated to direction,
|
||||
* and expanded to separate x and y conditions. */
|
||||
int i;
|
||||
double factor[2];
|
||||
factor[0] = asin((This->effect.direction * 3.0 * M_PI) / 0x7FFF);
|
||||
factor[1] = acos((This->effect.direction * 3.0 * M_PI) / 0x7FFF);
|
||||
for (i = 0; i < 2; ++i) {
|
||||
This->effect.u.condition[i].center = (int)(factor[i] * (tsp->lOffset / 10) * 32);
|
||||
This->effect.u.condition[i].right_coeff = (int)(factor[i] * (tsp->lPositiveCoefficient / 10) * 32);
|
||||
This->effect.u.condition[i].left_coeff = (int)(factor[i] * (tsp->lNegativeCoefficient / 10) * 32);
|
||||
This->effect.u.condition[i].right_saturation = (int)(factor[i] * (tsp->dwPositiveSaturation / 10) * 32);
|
||||
This->effect.u.condition[i].left_saturation = (int)(factor[i] * (tsp->dwNegativeSaturation / 10) * 32);
|
||||
This->effect.u.condition[i].deadband = (int)(factor[i] * (tsp->lDeadBand / 10) * 32);
|
||||
}
|
||||
} else if (peff->cbTypeSpecificParams == 2 * sizeof(DICONDITION)) {
|
||||
/* Two condition blocks. Direct parameter copy. */
|
||||
int i;
|
||||
for (i = 0; i < 2; ++i) {
|
||||
This->effect.u.condition[i].center = (tsp[i].lOffset / 10) * 32;
|
||||
This->effect.u.condition[i].right_coeff = (tsp[i].lPositiveCoefficient / 10) * 32;
|
||||
This->effect.u.condition[i].left_coeff = (tsp[i].lNegativeCoefficient / 10) * 32;
|
||||
This->effect.u.condition[i].right_saturation = (tsp[i].dwPositiveSaturation / 10) * 32;
|
||||
This->effect.u.condition[i].left_saturation = (tsp[i].dwNegativeSaturation / 10) * 32;
|
||||
This->effect.u.condition[i].deadband = (tsp[i].lDeadBand / 10) * 32;
|
||||
}
|
||||
} else {
|
||||
return DIERR_INVALIDPARAM;
|
||||
}
|
||||
} 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 ULONG WINAPI LinuxInputEffectImpl_Release(
|
||||
LPDIRECTINPUTEFFECT iface)
|
||||
{
|
||||
LinuxInputEffectImpl *This = (LinuxInputEffectImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&(This->ref));
|
||||
|
||||
if (ref == 0)
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI LinuxInputEffectImpl_Stop(
|
||||
LPDIRECTINPUTEFFECT iface)
|
||||
{
|
||||
struct input_event event;
|
||||
LinuxInputEffectImpl *This = (LinuxInputEffectImpl *)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 = (LinuxInputEffectImpl *)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;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* LinuxInputEffect
|
||||
*/
|
||||
|
||||
HRESULT linuxinput_create_effect(
|
||||
int* fd,
|
||||
REFGUID rguid,
|
||||
LPDIRECTINPUTEFFECT* peff)
|
||||
{
|
||||
LinuxInputEffectImpl* newEffect = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY, sizeof(LinuxInputEffectImpl));
|
||||
DWORD type = _typeFromGUID(rguid);
|
||||
|
||||
newEffect->lpVtbl = &LinuxInputEffectVtbl;
|
||||
newEffect->ref = 1;
|
||||
memcpy(&(newEffect->guid), rguid, sizeof(*rguid));
|
||||
newEffect->fd = fd;
|
||||
|
||||
/* 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("Unkown force type.\n");
|
||||
HeapFree(GetProcessHeap(), 0, newEffect);
|
||||
return DIERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* mark as non-uploaded */
|
||||
newEffect->effect.id = -1;
|
||||
|
||||
*peff = (LPDIRECTINPUTEFFECT)newEffect;
|
||||
|
||||
TRACE("Creating linux input system effect (%p) with guid %s\n",
|
||||
*peff, _dump_dinput_GUID(rguid));
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
HRESULT linuxinput_get_info_A(
|
||||
int fd,
|
||||
REFGUID rguid,
|
||||
LPDIEFFECTINFOA info)
|
||||
{
|
||||
DWORD type = _typeFromGUID(rguid);
|
||||
|
||||
TRACE("(%d, %s, %p) type=%ld\n", fd, _dump_dinput_GUID(rguid), info, type);
|
||||
|
||||
if (!info) return E_POINTER;
|
||||
|
||||
if (info->dwSize != sizeof(DIEFFECTINFOA)) 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) */
|
||||
strcpy((char*)&(info->tszName), _dump_dinput_GUID(rguid));
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
HRESULT linuxinput_get_info_W(
|
||||
int fd,
|
||||
REFGUID rguid,
|
||||
LPDIEFFECTINFOW info)
|
||||
{
|
||||
DWORD type = _typeFromGUID(rguid);
|
||||
|
||||
TRACE("(%d, %s, %p) type=%ld\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,
|
||||
(WCHAR*)&(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 */
|
|
@ -84,12 +84,12 @@ typedef struct {
|
|||
} POV;
|
||||
|
||||
typedef struct JoystickImpl JoystickImpl;
|
||||
static IDirectInputDevice8AVtbl JoystickAvt;
|
||||
static IDirectInputDevice8WVtbl JoystickWvt;
|
||||
static const IDirectInputDevice8AVtbl JoystickAvt;
|
||||
static const IDirectInputDevice8WVtbl JoystickWvt;
|
||||
struct JoystickImpl
|
||||
{
|
||||
LPVOID lpVtbl;
|
||||
DWORD ref;
|
||||
const void *lpVtbl;
|
||||
LONG ref;
|
||||
GUID guid;
|
||||
char dev[32];
|
||||
|
||||
|
@ -254,10 +254,10 @@ static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN
|
|||
inline static DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
|
||||
char *buffer, DWORD size )
|
||||
{
|
||||
if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, buffer, &size ))
|
||||
if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size ))
|
||||
return 0;
|
||||
|
||||
if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, buffer, &size ))
|
||||
if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size ))
|
||||
return 0;
|
||||
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
|
@ -269,28 +269,27 @@ inline static DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
|
|||
|
||||
static HRESULT setup_dinput_options(JoystickImpl * device)
|
||||
{
|
||||
char buffer[MAX_PATH+1];
|
||||
char buffer[MAX_PATH+16];
|
||||
HKEY hkey, appkey = 0;
|
||||
DWORD len;
|
||||
|
||||
buffer[MAX_PATH]='\0';
|
||||
|
||||
if (RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\dinput", &hkey)) hkey = 0;
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\DirectInput */
|
||||
if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\DirectInput", &hkey)) hkey = 0;
|
||||
|
||||
len = GetModuleFileNameA( 0, buffer, MAX_PATH );
|
||||
if (len && len < MAX_PATH) {
|
||||
HKEY tmpkey;
|
||||
|
||||
if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\AppDefaults", &tmpkey )) {
|
||||
char appname[MAX_PATH+16];
|
||||
char *p = strrchr( buffer, '\\' );
|
||||
if (p!=NULL) {
|
||||
strcpy(appname,p+1);
|
||||
strcat(appname,"\\dinput");
|
||||
TRACE("appname = [%s] \n",appname);
|
||||
if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
|
||||
}
|
||||
RegCloseKey( tmpkey );
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DirectInput */
|
||||
if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
|
||||
{
|
||||
char *p, *appname = buffer;
|
||||
if ((p = strrchr( appname, '/' ))) appname = p + 1;
|
||||
if ((p = strrchr( appname, '\\' ))) appname = p + 1;
|
||||
strcat( appname, "\\DirectInput" );
|
||||
if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
|
||||
RegCloseKey( tmpkey );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,7 +385,7 @@ static HRESULT setup_dinput_options(JoystickImpl * device)
|
|||
return DI_OK;
|
||||
}
|
||||
|
||||
void calculate_ids(JoystickImpl* device)
|
||||
static void calculate_ids(JoystickImpl* device)
|
||||
{
|
||||
int i;
|
||||
int axis = 0;
|
||||
|
@ -437,7 +436,7 @@ void calculate_ids(JoystickImpl* device)
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *dinput, LPDIRECTINPUTDEVICEA* pdev)
|
||||
static HRESULT alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput, LPDIRECTINPUTDEVICEA* pdev)
|
||||
{
|
||||
DWORD i;
|
||||
JoystickImpl* newDevice;
|
||||
|
@ -553,7 +552,7 @@ static HRESULT alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *dinput,
|
|||
|
||||
IDirectInputDevice_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->dinput);
|
||||
InitializeCriticalSection(&(newDevice->crit));
|
||||
newDevice->crit.DebugInfo->Spare[1] = (DWORD)"DINPUT_Mouse";
|
||||
newDevice->crit.DebugInfo->Spare[0] = (DWORD_PTR)"DINPUT_Mouse";
|
||||
|
||||
newDevice->devcaps.dwSize = sizeof(newDevice->devcaps);
|
||||
newDevice->devcaps.dwFlags = DIDC_ATTACHED;
|
||||
|
@ -689,7 +688,7 @@ static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
|
|||
/* release the data transform filter */
|
||||
release_DataFormat(This->transform);
|
||||
|
||||
This->crit.DebugInfo->Spare[1] = 0;
|
||||
This->crit.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&(This->crit));
|
||||
IDirectInputDevice_Release((LPDIRECTINPUTDEVICE8A)This->dinput);
|
||||
|
||||
|
@ -831,7 +830,7 @@ static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
|
|||
return DI_NOEFFECT;
|
||||
}
|
||||
|
||||
LONG map_axis(JoystickImpl * This, short val, short index)
|
||||
static LONG map_axis(JoystickImpl * This, short val, short index)
|
||||
{
|
||||
double fval = val;
|
||||
double fmin = This->props[index].lMin;
|
||||
|
@ -849,7 +848,7 @@ LONG map_axis(JoystickImpl * This, short val, short index)
|
|||
}
|
||||
|
||||
/* convert wine format offset to user format object index */
|
||||
int offset_to_object(JoystickImpl *This, int offset)
|
||||
static int offset_to_object(JoystickImpl *This, int offset)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1094,7 +1093,7 @@ static HRESULT WINAPI JoystickAImpl_GetDeviceData(
|
|||
return hr;
|
||||
}
|
||||
|
||||
int find_property(JoystickImpl * This, LPCDIPROPHEADER ph)
|
||||
static int find_property(JoystickImpl * This, LPCDIPROPHEADER ph)
|
||||
{
|
||||
int i;
|
||||
if (ph->dwHow == DIPH_BYOFFSET) {
|
||||
|
@ -1132,7 +1131,7 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(
|
|||
_dump_DIPROPHEADER(ph);
|
||||
|
||||
if (!HIWORD(rguid)) {
|
||||
switch ((DWORD)rguid) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
|
||||
TRACE("buffersize = %ld\n",pd->dwData);
|
||||
|
@ -1197,7 +1196,7 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(
|
|||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
|
||||
FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1213,7 +1212,7 @@ static HRESULT WINAPI JoystickAImpl_SetEventNotification(
|
|||
) {
|
||||
JoystickImpl *This = (JoystickImpl *)iface;
|
||||
|
||||
TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
|
||||
TRACE("(this=%p,%p)\n",This,hnd);
|
||||
This->hEvent = hnd;
|
||||
return DI_OK;
|
||||
}
|
||||
|
@ -1428,7 +1427,7 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(
|
|||
_dump_DIPROPHEADER(pdiph);
|
||||
|
||||
if (!HIWORD(rguid)) {
|
||||
switch ((DWORD)rguid) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
|
||||
TRACE(" return buffersize = %d\n",This->queue_len);
|
||||
|
@ -1469,7 +1468,7 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(
|
|||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
|
||||
FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1640,7 +1639,7 @@ HRESULT WINAPI JoystickWImpl_GetDeviceInfo(
|
|||
return DI_OK;
|
||||
}
|
||||
|
||||
static IDirectInputDevice8AVtbl JoystickAvt =
|
||||
static const IDirectInputDevice8AVtbl JoystickAvt =
|
||||
{
|
||||
IDirectInputDevice2AImpl_QueryInterface,
|
||||
IDirectInputDevice2AImpl_AddRef,
|
||||
|
@ -1682,7 +1681,7 @@ static IDirectInputDevice8AVtbl JoystickAvt =
|
|||
# define XCAST(fun) (void*)
|
||||
#endif
|
||||
|
||||
static IDirectInputDevice8WVtbl SysJoystickWvt =
|
||||
static const IDirectInputDevice8WVtbl SysJoystickWvt =
|
||||
{
|
||||
IDirectInputDevice2WImpl_QueryInterface,
|
||||
XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* 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
|
||||
|
@ -43,6 +44,9 @@
|
|||
#endif
|
||||
#ifdef HAVE_LINUX_INPUT_H
|
||||
# include <linux/input.h>
|
||||
# if defined(EVIOCGBIT) && defined(EV_ABS) && defined(BTN_PINKIE)
|
||||
# define HAVE_CORRECT_LINUXINPUT_H
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
@ -65,13 +69,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput);
|
|||
#define WINE_JOYSTICK_AXIS_BASE 0
|
||||
#define WINE_JOYSTICK_BUTTON_BASE 8
|
||||
|
||||
typedef struct EffectListItem EffectListItem;
|
||||
struct EffectListItem
|
||||
{
|
||||
LPDIRECTINPUTEFFECT ref;
|
||||
struct EffectListItem* next;
|
||||
};
|
||||
|
||||
/* implemented in effect_linuxinput.c */
|
||||
HRESULT linuxinput_create_effect(int* fd, REFGUID rguid, LPDIRECTINPUTEFFECT* peff);
|
||||
HRESULT linuxinput_get_info_A(int fd, REFGUID rguid, LPDIEFFECTINFOA info);
|
||||
HRESULT linuxinput_get_info_W(int fd, REFGUID rguid, LPDIEFFECTINFOW info);
|
||||
|
||||
typedef struct JoystickImpl JoystickImpl;
|
||||
static IDirectInputDevice8AVtbl JoystickAvt;
|
||||
static IDirectInputDevice8WVtbl JoystickWvt;
|
||||
static const IDirectInputDevice8AVtbl JoystickAvt;
|
||||
static const IDirectInputDevice8WVtbl JoystickWvt;
|
||||
struct JoystickImpl
|
||||
{
|
||||
LPVOID lpVtbl;
|
||||
DWORD ref;
|
||||
const void *lpVtbl;
|
||||
LONG ref;
|
||||
GUID guid;
|
||||
|
||||
|
||||
|
@ -97,6 +113,12 @@ struct JoystickImpl
|
|||
BOOL overflow;
|
||||
DIJOYSTATE2 js;
|
||||
|
||||
/* Force feedback variables */
|
||||
BOOL has_ff;
|
||||
int num_effects;
|
||||
EffectListItem* top_effect;
|
||||
int ff_state;
|
||||
|
||||
/* data returned by the EVIOCGABS() ioctl */
|
||||
int axes[ABS_MAX+1][5];
|
||||
|
||||
|
@ -107,9 +129,11 @@ struct JoystickImpl
|
|||
#define AXE_ABSFLAT 4
|
||||
|
||||
|
||||
/* data returned by EVIOCGBIT for EV_ABS and EV_KEY */
|
||||
/* 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];
|
||||
};
|
||||
|
||||
/* This GUID is slightly different from the linux joystick one. Take note. */
|
||||
|
@ -124,17 +148,24 @@ static void fake_current_js_state(JoystickImpl *ji);
|
|||
|
||||
#define test_bit(arr,bit) (((BYTE*)arr)[bit>>3]&(1<<(bit&7)))
|
||||
|
||||
static int joydev_have(void)
|
||||
static int joydev_have(BOOL require_ff)
|
||||
{
|
||||
int i, fd;
|
||||
int i, fd, flags, num_effects;
|
||||
int havejoy = 0;
|
||||
|
||||
for (i=0;i<64;i++) {
|
||||
char buf[200];
|
||||
BYTE absbits[(ABS_MAX+7)/8],keybits[(KEY_MAX+7)/8];
|
||||
BYTE evbits[(EV_MAX+7)/8],ffbits[(FF_MAX+7)/8];
|
||||
|
||||
sprintf(buf,EVDEVPREFIX"%d",i);
|
||||
if (-1!=(fd=open(buf,O_RDONLY))) {
|
||||
|
||||
if (require_ff)
|
||||
flags = O_RDWR;
|
||||
else
|
||||
flags = O_RDONLY;
|
||||
|
||||
if (-1!=(fd=open(buf,flags))) {
|
||||
if (-1==ioctl(fd,EVIOCGBIT(EV_ABS,sizeof(absbits)),absbits)) {
|
||||
perror("EVIOCGBIT EV_ABS");
|
||||
close(fd);
|
||||
|
@ -145,6 +176,23 @@ static int joydev_have(void)
|
|||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* test for force feedback if it's required */
|
||||
if (require_ff) {
|
||||
if ((-1==ioctl(fd,EVIOCGBIT(0,sizeof(evbits)),evbits))) {
|
||||
perror("EVIOCGBIT 0");
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
if ( (!test_bit(evbits,EV_FF))
|
||||
|| (-1==ioctl(fd,EVIOCGBIT(EV_FF,sizeof(ffbits)),ffbits))
|
||||
|| (-1==ioctl(fd,EVIOCGEFFECTS,&num_effects))
|
||||
|| (num_effects <= 0)) {
|
||||
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(absbits,ABS_X) && test_bit(absbits,ABS_Y) &&
|
||||
|
@ -176,10 +224,12 @@ static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN
|
|||
(((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))))
|
||||
return FALSE;
|
||||
|
||||
#ifndef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
if (dwFlags & DIEDFL_FORCEFEEDBACK)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
havejoy = joydev_have();
|
||||
havejoy = joydev_have(dwFlags & DIEDFL_FORCEFEEDBACK);
|
||||
|
||||
if (!havejoy)
|
||||
return FALSE;
|
||||
|
@ -214,10 +264,12 @@ static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN
|
|||
(((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))))
|
||||
return FALSE;
|
||||
|
||||
#ifndef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
if (dwFlags & DIEDFL_FORCEFEEDBACK)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
havejoy = joydev_have();
|
||||
havejoy = joydev_have(dwFlags & DIEDFL_FORCEFEEDBACK);
|
||||
|
||||
if (!havejoy)
|
||||
return FALSE;
|
||||
|
@ -240,7 +292,7 @@ static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static JoystickImpl *alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *dinput)
|
||||
static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput)
|
||||
{
|
||||
JoystickImpl* newDevice;
|
||||
int i;
|
||||
|
@ -250,6 +302,9 @@ static JoystickImpl *alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *d
|
|||
newDevice->ref = 1;
|
||||
newDevice->joyfd = -1;
|
||||
newDevice->dinput = dinput;
|
||||
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
newDevice->ff_state = FF_STATUS_STOPPED;
|
||||
#endif
|
||||
memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
|
||||
for (i=0;i<ABS_MAX;i++) {
|
||||
newDevice->wantmin[i] = -32768;
|
||||
|
@ -269,7 +324,7 @@ static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, RE
|
|||
{
|
||||
int havejoy = 0;
|
||||
|
||||
havejoy = joydev_have();
|
||||
havejoy = joydev_have(FALSE);
|
||||
|
||||
if (!havejoy)
|
||||
return DIERR_DEVICENOTREG;
|
||||
|
@ -296,7 +351,7 @@ static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, RE
|
|||
{
|
||||
int havejoy = 0;
|
||||
|
||||
havejoy = joydev_have();
|
||||
havejoy = joydev_have(FALSE);
|
||||
|
||||
if (!havejoy)
|
||||
return DIERR_DEVICENOTREG;
|
||||
|
@ -338,6 +393,9 @@ static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
|
|||
if (ref)
|
||||
return ref;
|
||||
|
||||
/* Reset the FF state, free all effects, etc */
|
||||
IDirectInputDevice8_SendForceFeedbackCommand(iface, DISFFC_RESET);
|
||||
|
||||
/* Free the data queue */
|
||||
HeapFree(GetProcessHeap(),0,This->data_queue);
|
||||
|
||||
|
@ -379,19 +437,32 @@ static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
|
|||
int i;
|
||||
JoystickImpl *This = (JoystickImpl *)iface;
|
||||
char buf[200];
|
||||
BOOL readonly = TRUE;
|
||||
|
||||
TRACE("(this=%p)\n",This);
|
||||
if (This->joyfd!=-1)
|
||||
return 0;
|
||||
for (i=0;i<64;i++) {
|
||||
sprintf(buf,EVDEVPREFIX"%d",i);
|
||||
if (-1==(This->joyfd=open(buf,O_RDONLY))) {
|
||||
if (errno==ENODEV)
|
||||
return DIERR_NOTFOUND;
|
||||
perror(buf);
|
||||
continue;
|
||||
if (-1==(This->joyfd=open(buf,O_RDWR))) {
|
||||
if (-1==(This->joyfd=open(buf,O_RDONLY))) {
|
||||
/* Couldn't open the device at all */
|
||||
if (errno==ENODEV)
|
||||
return DIERR_NOTFOUND;
|
||||
perror(buf);
|
||||
continue;
|
||||
}
|
||||
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",buf);
|
||||
}
|
||||
}
|
||||
if ((-1!=ioctl(This->joyfd,EVIOCGBIT(EV_ABS,sizeof(This->absbits)),This->absbits)) &&
|
||||
else {
|
||||
/* Opened device in read-write */
|
||||
readonly = FALSE;
|
||||
}
|
||||
if ((-1!=ioctl(This->joyfd,EVIOCGBIT(0,sizeof(This->evbits)),This->evbits)) &&
|
||||
(-1!=ioctl(This->joyfd,EVIOCGBIT(EV_ABS,sizeof(This->absbits)),This->absbits)) &&
|
||||
(-1!=ioctl(This->joyfd,EVIOCGBIT(EV_KEY,sizeof(This->keybits)),This->keybits)) &&
|
||||
(test_bit(This->absbits,ABS_X) && test_bit(This->absbits,ABS_Y) &&
|
||||
(test_bit(This->keybits,BTN_TRIGGER)||
|
||||
|
@ -407,6 +478,30 @@ static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
|
|||
if (This->joyfd==-1)
|
||||
return DIERR_NOTFOUND;
|
||||
|
||||
This->has_ff = FALSE;
|
||||
This->num_effects = 0;
|
||||
|
||||
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
if (!readonly && test_bit(This->evbits, EV_FF)) {
|
||||
if (-1!=ioctl(This->joyfd,EVIOCGBIT(EV_FF,sizeof(This->ffbits)),This->ffbits)) {
|
||||
if (-1!=ioctl(This->joyfd,EVIOCGEFFECTS,&This->num_effects)
|
||||
&& This->num_effects > 0) {
|
||||
This->has_ff = TRUE;
|
||||
TRACE("Joystick seems to be capable of force feedback.\n");
|
||||
}
|
||||
else {
|
||||
TRACE("Joystick does not support any effects, disabling force feedback.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRACE("Could not get EV_FF bits; disabling force feedback.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRACE("Force feedback disabled (device is readonly or joystick incapable).\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i=0;i<ABS_MAX;i++) {
|
||||
if (test_bit(This->absbits,i)) {
|
||||
if (-1==ioctl(This->joyfd,EVIOCGABS(i),&(This->axes[i])))
|
||||
|
@ -468,7 +563,9 @@ map_axis(JoystickImpl* This, int axis, int val) {
|
|||
if (xmin == xmax) return val;
|
||||
|
||||
/* map the value from the hmin-hmax range into the wmin-wmax range */
|
||||
ret = (val * (wmax-wmin)) / (hmax-hmin) + wmin;
|
||||
ret = ((val-hmin) * (wmax-wmin)) / (hmax-hmin) + wmin;
|
||||
|
||||
TRACE("xmin=%d xmax=%d hmin=%d hmax=%d wmin=%d wmax=%d val=%d ret=%d\n", xmin, xmax, hmin, hmax, wmin, wmax, val, ret);
|
||||
|
||||
#if 0
|
||||
/* deadzone doesn't work comfortably enough right now. needs more testing*/
|
||||
|
@ -492,6 +589,8 @@ static void fake_current_js_state(JoystickImpl *ji)
|
|||
ji->js.lRx = map_axis(ji, ABS_RX, ji->axes[ABS_RX][AXE_ABS]);
|
||||
ji->js.lRy = map_axis(ji, ABS_RY, ji->axes[ABS_RY][AXE_ABS]);
|
||||
ji->js.lRz = map_axis(ji, ABS_RZ, ji->axes[ABS_RZ][AXE_ABS]);
|
||||
ji->js.rglSlider[0] = map_axis(ji, ABS_THROTTLE, ji->axes[ABS_THROTTLE][AXE_ABS]);
|
||||
ji->js.rglSlider[1] = map_axis(ji, ABS_RUDDER, ji->axes[ABS_RUDDER ][AXE_ABS]);
|
||||
}
|
||||
|
||||
static void joy_polldev(JoystickImpl *This) {
|
||||
|
@ -613,11 +712,24 @@ static void joy_polldev(JoystickImpl *This) {
|
|||
This->js.lRz = map_axis(This,ABS_RZ,ie.value);
|
||||
GEN_EVENT(DIJOFS_RZ,This->js.lRz,ie.time.tv_usec,(This->dinput->evsequence)++);
|
||||
break;
|
||||
case ABS_THROTTLE:
|
||||
This->js.rglSlider[0] = map_axis(This,ABS_THROTTLE,ie.value);
|
||||
GEN_EVENT(DIJOFS_SLIDER(0),This->js.rglSlider[0],ie.time.tv_usec,(This->dinput->evsequence)++);
|
||||
break;
|
||||
case ABS_RUDDER:
|
||||
This->js.rglSlider[1] = map_axis(This,ABS_RUDDER,ie.value);
|
||||
GEN_EVENT(DIJOFS_SLIDER(1),This->js.rglSlider[1],ie.time.tv_usec,(This->dinput->evsequence)++);
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled joystick axe event (code %d, value %d)\n",ie.code,ie.value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
case EV_FF_STATUS:
|
||||
This->ff_state = ie.value;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
FIXME("joystick cannot handle type %d event (code %d)\n",ie.type,ie.code);
|
||||
break;
|
||||
|
@ -683,7 +795,7 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow);
|
||||
|
||||
if (!HIWORD(rguid)) {
|
||||
switch ((DWORD)rguid) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
|
||||
|
||||
|
@ -701,6 +813,8 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
case 12: /* Rx */
|
||||
case 16: /* Ry */
|
||||
case 20: /* Rz */
|
||||
case 24: /* Slider 0 -> Throttle */
|
||||
case 28: /* Slider 1 -> Rudder */
|
||||
This->wantmin[ph->dwObj/4] = pr->lMin;
|
||||
This->wantmax[ph->dwObj/4] = pr->lMax;
|
||||
break;
|
||||
|
@ -717,7 +831,7 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
|
||||
FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -733,7 +847,7 @@ static HRESULT WINAPI JoystickAImpl_SetEventNotification(
|
|||
) {
|
||||
JoystickImpl *This = (JoystickImpl *)iface;
|
||||
|
||||
TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
|
||||
TRACE("(this=%p,%p)\n",This,hnd);
|
||||
This->hEvent = hnd;
|
||||
return DI_OK;
|
||||
}
|
||||
|
@ -765,6 +879,9 @@ static HRESULT WINAPI JoystickAImpl_GetCapabilities(
|
|||
buttons=0;
|
||||
for (i=0;i<KEY_MAX;i++) if (test_bit(This->keybits,i)) buttons++;
|
||||
|
||||
if (This->has_ff)
|
||||
lpDIDevCaps->dwFlags |= DIDC_FORCEFEEDBACK;
|
||||
|
||||
lpDIDevCaps->dwAxes = axes;
|
||||
lpDIDevCaps->dwButtons = buttons;
|
||||
|
||||
|
@ -795,7 +912,6 @@ static HRESULT WINAPI JoystickAImpl_EnumObjects(
|
|||
DIDEVICEOBJECTINSTANCEA ddoi;
|
||||
int xfd = This->joyfd;
|
||||
|
||||
|
||||
TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags);
|
||||
if (TRACE_ON(dinput)) {
|
||||
TRACE(" - flags = ");
|
||||
|
@ -803,7 +919,9 @@ static HRESULT WINAPI JoystickAImpl_EnumObjects(
|
|||
TRACE("\n");
|
||||
}
|
||||
|
||||
if (xfd == -1) return DIERR_NOTACQUIRED;
|
||||
/* We need to work even if we're not yet acquired */
|
||||
if (xfd == -1)
|
||||
IDirectInputDevice8_Acquire(iface);
|
||||
|
||||
/* Only the fields till dwFFMaxForce are relevant */
|
||||
ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce);
|
||||
|
@ -846,14 +964,27 @@ static HRESULT WINAPI JoystickAImpl_EnumObjects(
|
|||
ddoi.guidType = GUID_Slider;
|
||||
ddoi.dwOfs = DIJOFS_SLIDER(0);
|
||||
break;
|
||||
case ABS_RUDDER:
|
||||
ddoi.guidType = GUID_Slider;
|
||||
ddoi.dwOfs = DIJOFS_SLIDER(1);
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled abs axis %d, ignoring!\n",i);
|
||||
}
|
||||
ddoi.dwType = DIDFT_MAKEINSTANCE((1<<i) << WINE_JOYSTICK_AXIS_BASE) | DIDFT_ABSAXIS;
|
||||
/* Linux event force feedback supports only (and always) x and y axes */
|
||||
if (i == ABS_X || i == ABS_Y) {
|
||||
if (This->has_ff)
|
||||
ddoi.dwFlags |= DIDOI_FFACTUATOR;
|
||||
}
|
||||
sprintf(ddoi.tszName, "%d-Axis", i);
|
||||
_dump_OBJECTINSTANCEA(&ddoi);
|
||||
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE)
|
||||
return DI_OK;
|
||||
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) {
|
||||
/* return to unaquired state if that's where we were */
|
||||
if (xfd == -1)
|
||||
IDirectInputDevice8_Unacquire(iface);
|
||||
return DI_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -936,13 +1067,18 @@ static HRESULT WINAPI JoystickAImpl_EnumObjects(
|
|||
}
|
||||
sprintf(ddoi.tszName, "%d-Button", i);
|
||||
_dump_OBJECTINSTANCEA(&ddoi);
|
||||
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE)
|
||||
return DI_OK;
|
||||
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) {
|
||||
/* return to unaquired state if that's where we were */
|
||||
if (xfd == -1)
|
||||
IDirectInputDevice8_Unacquire(iface);
|
||||
return DI_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xfd!=This->joyfd)
|
||||
close(xfd);
|
||||
/* return to unaquired state if that's where we were */
|
||||
if (xfd == -1)
|
||||
IDirectInputDevice8_Unacquire(iface);
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
@ -978,7 +1114,7 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
_dump_DIPROPHEADER(pdiph);
|
||||
|
||||
if (!HIWORD(rguid)) {
|
||||
switch ((DWORD)rguid) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
|
||||
|
||||
|
@ -999,7 +1135,7 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
}
|
||||
|
||||
default:
|
||||
FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
|
||||
FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1008,7 +1144,351 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
return DI_OK;
|
||||
}
|
||||
|
||||
static IDirectInputDevice8AVtbl JoystickAvt =
|
||||
/******************************************************************************
|
||||
* CreateEffect - Create a new FF effect with the specified params
|
||||
*/
|
||||
static HRESULT WINAPI JoystickAImpl_CreateEffect(LPDIRECTINPUTDEVICE8A iface,
|
||||
REFGUID rguid,
|
||||
LPCDIEFFECT lpeff,
|
||||
LPDIRECTINPUTEFFECT *ppdef,
|
||||
LPUNKNOWN pUnkOuter)
|
||||
{
|
||||
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
EffectListItem* new = NULL;
|
||||
HRESULT retval = DI_OK;
|
||||
#endif
|
||||
|
||||
JoystickImpl* This = (JoystickImpl*)iface;
|
||||
TRACE("(this=%p,%p,%p,%p,%p)\n", This, rguid, lpeff, ppdef, pUnkOuter);
|
||||
|
||||
#ifndef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
TRACE("not available (compiled w/o ff support)\n");
|
||||
*ppdef = NULL;
|
||||
return DI_OK;
|
||||
#else
|
||||
|
||||
new = malloc(sizeof(EffectListItem));
|
||||
new->next = This->top_effect;
|
||||
This->top_effect = new;
|
||||
|
||||
retval = linuxinput_create_effect(&(This->joyfd), rguid, &(new->ref));
|
||||
if (retval != DI_OK)
|
||||
return retval;
|
||||
|
||||
if (lpeff != NULL)
|
||||
retval = IDirectInputEffect_SetParameters(new->ref, lpeff, 0);
|
||||
if (retval != DI_OK && retval != DI_DOWNLOADSKIPPED)
|
||||
return retval;
|
||||
|
||||
*ppdef = new->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 JoystickAImpl_EnumEffects(LPDIRECTINPUTDEVICE8A iface,
|
||||
LPDIENUMEFFECTSCALLBACKA lpCallback,
|
||||
LPVOID pvRef,
|
||||
DWORD dwEffType)
|
||||
{
|
||||
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
DIEFFECTINFOA dei; /* feif */
|
||||
DWORD type = DIEFT_GETTYPE(dwEffType);
|
||||
JoystickImpl* This = (JoystickImpl*)iface;
|
||||
int xfd = This->joyfd;
|
||||
|
||||
TRACE("(this=%p,%p,%ld) type=%ld fd=%d\n", This, pvRef, dwEffType, type, xfd);
|
||||
|
||||
dei.dwSize = sizeof(DIEFFECTINFOA);
|
||||
|
||||
/* We need to return something even if we're not yet acquired */
|
||||
if (xfd == -1)
|
||||
IDirectInputDevice8_Acquire(iface);
|
||||
|
||||
if ((type == DIEFT_ALL || type == DIEFT_CONSTANTFORCE)
|
||||
&& test_bit(This->ffbits, FF_CONSTANT)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_ConstantForce);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
|
||||
if ((type == DIEFT_ALL || type == DIEFT_PERIODIC)
|
||||
&& test_bit(This->ffbits, FF_PERIODIC)) {
|
||||
if (test_bit(This->ffbits, FF_SQUARE)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Square);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_SINE)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Sine);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_TRIANGLE)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Triangle);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_SAW_UP)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothUp);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_SAW_DOWN)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothDown);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
}
|
||||
|
||||
if ((type == DIEFT_ALL || type == DIEFT_RAMPFORCE)
|
||||
&& test_bit(This->ffbits, FF_RAMP)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_RampForce);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
|
||||
if (type == DIEFT_ALL || type == DIEFT_CONDITION) {
|
||||
if (test_bit(This->ffbits, FF_SPRING)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Spring);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_DAMPER)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Damper);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_INERTIA)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Inertia);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_FRICTION)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Friction);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
}
|
||||
|
||||
/* return to unaquired state if that's where it was */
|
||||
if (xfd == -1)
|
||||
IDirectInputDevice8_Unacquire(iface);
|
||||
#endif
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
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 = (JoystickImpl*)iface;
|
||||
int xfd = This->joyfd;
|
||||
|
||||
TRACE("(this=%p,%p,%ld) type=%ld fd=%d\n", This, pvRef, dwEffType, type, xfd);
|
||||
|
||||
dei.dwSize = sizeof(DIEFFECTINFOW);
|
||||
|
||||
/* We need to return something even if we're not yet acquired */
|
||||
if (xfd == -1)
|
||||
IDirectInputDevice8_Acquire(iface);
|
||||
|
||||
if ((type == DIEFT_ALL || type == DIEFT_CONSTANTFORCE)
|
||||
&& test_bit(This->ffbits, FF_CONSTANT)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_ConstantForce);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
|
||||
if ((type == DIEFT_ALL || type == DIEFT_PERIODIC)
|
||||
&& test_bit(This->ffbits, FF_PERIODIC)) {
|
||||
if (test_bit(This->ffbits, FF_SQUARE)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Square);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_SINE)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Sine);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_TRIANGLE)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Triangle);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_SAW_UP)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothUp);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_SAW_DOWN)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothDown);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
}
|
||||
|
||||
if ((type == DIEFT_ALL || type == DIEFT_RAMPFORCE)
|
||||
&& test_bit(This->ffbits, FF_RAMP)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_RampForce);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
|
||||
if (type == DIEFT_ALL || type == DIEFT_CONDITION) {
|
||||
if (test_bit(This->ffbits, FF_SPRING)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Spring);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_DAMPER)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Damper);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_INERTIA)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Inertia);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
if (test_bit(This->ffbits, FF_FRICTION)) {
|
||||
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Friction);
|
||||
(*lpCallback)(&dei, pvRef);
|
||||
}
|
||||
}
|
||||
|
||||
/* return to unaquired 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 JoystickAImpl_GetEffectInfo(LPDIRECTINPUTDEVICE8A iface,
|
||||
LPDIEFFECTINFOA pdei,
|
||||
REFGUID guid)
|
||||
{
|
||||
JoystickImpl* This = (JoystickImpl*)iface;
|
||||
|
||||
TRACE("(this=%p,%p,%s)\n", This, pdei, _dump_dinput_GUID(guid));
|
||||
|
||||
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
return linuxinput_get_info_A(This->joyfd, guid, pdei);
|
||||
#else
|
||||
return DI_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
static HRESULT WINAPI JoystickWImpl_GetEffectInfo(LPDIRECTINPUTDEVICE8W iface,
|
||||
LPDIEFFECTINFOW pdei,
|
||||
REFGUID guid)
|
||||
{
|
||||
JoystickImpl* This = (JoystickImpl*)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 JoystickAImpl_GetForceFeedbackState(
|
||||
LPDIRECTINPUTDEVICE8A iface,
|
||||
LPDWORD pdwOut)
|
||||
{
|
||||
JoystickImpl* This = (JoystickImpl*)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 JoystickAImpl_SendForceFeedbackCommand(
|
||||
LPDIRECTINPUTDEVICE8A iface,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
JoystickImpl* This = (JoystickImpl*)iface;
|
||||
TRACE("(this=%p,%ld)\n", This, dwFlags);
|
||||
|
||||
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||
if (dwFlags == DISFFC_STOPALL) {
|
||||
/* Stop all effects */
|
||||
EffectListItem* itr = This->top_effect;
|
||||
while (itr) {
|
||||
IDirectInputEffect_Stop(itr->ref);
|
||||
itr = itr->next;
|
||||
}
|
||||
} else if (dwFlags == DISFFC_RESET) {
|
||||
/* Stop, unload, release and free all effects */
|
||||
/* This returns the device to its "bare" state */
|
||||
while (This->top_effect) {
|
||||
EffectListItem* temp = This->top_effect;
|
||||
IDirectInputEffect_Stop(temp->ref);
|
||||
IDirectInputEffect_Unload(temp->ref);
|
||||
IDirectInputEffect_Release(temp->ref);
|
||||
This->top_effect = temp->next;
|
||||
free(temp);
|
||||
}
|
||||
} else if (dwFlags == DISFFC_PAUSE || dwFlags == DISFFC_CONTINUE) {
|
||||
FIXME("No support for Pause or Continue in linux\n");
|
||||
} else if (dwFlags == DISFFC_SETACTUATORSOFF
|
||||
|| dwFlags == DISFFC_SETACTUATORSON) {
|
||||
FIXME("No direct actuator control in linux\n");
|
||||
} else {
|
||||
FIXME("Unknown Force Feedback Command!\n");
|
||||
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 JoystickAImpl_EnumCreatedEffectObjects(
|
||||
LPDIRECTINPUTDEVICE8A iface,
|
||||
LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
|
||||
LPVOID pvRef,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
/* this function is safe to call on non-ff-enabled builds */
|
||||
|
||||
JoystickImpl* This = (JoystickImpl*)iface;
|
||||
EffectListItem* itr = This->top_effect;
|
||||
TRACE("(this=%p,%p,%p,%ld)\n", This, lpCallback, pvRef, dwFlags);
|
||||
|
||||
if (!lpCallback)
|
||||
return DIERR_INVALIDPARAM;
|
||||
|
||||
if (dwFlags != 0)
|
||||
FIXME("Flags specified, but no flags exist yet (DX9)!");
|
||||
|
||||
while (itr) {
|
||||
(*lpCallback)(itr->ref, pvRef);
|
||||
itr = itr->next;
|
||||
}
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static const IDirectInputDevice8AVtbl JoystickAvt =
|
||||
{
|
||||
IDirectInputDevice2AImpl_QueryInterface,
|
||||
IDirectInputDevice2AImpl_AddRef,
|
||||
|
@ -1028,12 +1508,12 @@ static IDirectInputDevice8AVtbl JoystickAvt =
|
|||
IDirectInputDevice2AImpl_GetDeviceInfo,
|
||||
IDirectInputDevice2AImpl_RunControlPanel,
|
||||
IDirectInputDevice2AImpl_Initialize,
|
||||
IDirectInputDevice2AImpl_CreateEffect,
|
||||
IDirectInputDevice2AImpl_EnumEffects,
|
||||
IDirectInputDevice2AImpl_GetEffectInfo,
|
||||
IDirectInputDevice2AImpl_GetForceFeedbackState,
|
||||
IDirectInputDevice2AImpl_SendForceFeedbackCommand,
|
||||
IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
|
||||
JoystickAImpl_CreateEffect,
|
||||
JoystickAImpl_EnumEffects,
|
||||
JoystickAImpl_GetEffectInfo,
|
||||
JoystickAImpl_GetForceFeedbackState,
|
||||
JoystickAImpl_SendForceFeedbackCommand,
|
||||
JoystickAImpl_EnumCreatedEffectObjects,
|
||||
IDirectInputDevice2AImpl_Escape,
|
||||
JoystickAImpl_Poll,
|
||||
IDirectInputDevice2AImpl_SendDeviceData,
|
||||
|
@ -1050,7 +1530,7 @@ static IDirectInputDevice8AVtbl JoystickAvt =
|
|||
# define XCAST(fun) (void*)
|
||||
#endif
|
||||
|
||||
static IDirectInputDevice8WVtbl JoystickWvt =
|
||||
static const IDirectInputDevice8WVtbl JoystickWvt =
|
||||
{
|
||||
IDirectInputDevice2WImpl_QueryInterface,
|
||||
XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
|
||||
|
@ -1070,12 +1550,12 @@ static IDirectInputDevice8WVtbl JoystickWvt =
|
|||
IDirectInputDevice2WImpl_GetDeviceInfo,
|
||||
XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
|
||||
XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
|
||||
XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
|
||||
IDirectInputDevice2WImpl_EnumEffects,
|
||||
IDirectInputDevice2WImpl_GetEffectInfo,
|
||||
XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState,
|
||||
XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
|
||||
XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
|
||||
XCAST(CreateEffect)JoystickAImpl_CreateEffect,
|
||||
JoystickWImpl_EnumEffects,
|
||||
JoystickWImpl_GetEffectInfo,
|
||||
XCAST(GetForceFeedbackState)JoystickAImpl_GetForceFeedbackState,
|
||||
XCAST(SendForceFeedbackCommand)JoystickAImpl_SendForceFeedbackCommand,
|
||||
XCAST(EnumCreatedEffectObjects)JoystickAImpl_EnumCreatedEffectObjects,
|
||||
XCAST(Escape)IDirectInputDevice2AImpl_Escape,
|
||||
XCAST(Poll)JoystickAImpl_Poll,
|
||||
XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
|
||||
|
|
|
@ -40,14 +40,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput);
|
|||
|
||||
#define WINE_DINPUT_KEYBOARD_MAX_KEYS 256
|
||||
|
||||
static IDirectInputDevice8AVtbl SysKeyboardAvt;
|
||||
static IDirectInputDevice8WVtbl SysKeyboardWvt;
|
||||
static const IDirectInputDevice8AVtbl SysKeyboardAvt;
|
||||
static const IDirectInputDevice8WVtbl SysKeyboardWvt;
|
||||
|
||||
typedef struct SysKeyboardImpl SysKeyboardImpl;
|
||||
struct SysKeyboardImpl
|
||||
{
|
||||
LPVOID lpVtbl;
|
||||
DWORD ref;
|
||||
const void *lpVtbl;
|
||||
LONG ref;
|
||||
GUID guid;
|
||||
|
||||
IDirectInputImpl* dinput;
|
||||
|
@ -83,11 +83,11 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
|
|||
{
|
||||
0, 0, &keyboard_crit,
|
||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
0, 0, { 0, (DWORD)(__FILE__ ": keyboard_crit") }
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": keyboard_crit") }
|
||||
};
|
||||
static CRITICAL_SECTION keyboard_crit = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static DWORD keyboard_users = 0;
|
||||
static LONG keyboard_users = 0;
|
||||
static HHOOK keyboard_hook = NULL;
|
||||
|
||||
LRESULT CALLBACK KeyboardCallback( int code, WPARAM wparam, LPARAM lparam )
|
||||
|
@ -238,7 +238,7 @@ static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEI
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static SysKeyboardImpl *alloc_device(REFGUID rguid, LPVOID kvt, IDirectInputImpl *dinput)
|
||||
static SysKeyboardImpl *alloc_device(REFGUID rguid, const void *kvt, IDirectInputImpl *dinput)
|
||||
{
|
||||
SysKeyboardImpl* newDevice;
|
||||
DWORD kbd_users;
|
||||
|
@ -342,7 +342,7 @@ static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
|
|||
TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
|
||||
ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
|
||||
if (!HIWORD(rguid)) {
|
||||
switch ((DWORD)rguid) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
|
||||
|
||||
|
@ -356,7 +356,7 @@ static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
|
|||
break;
|
||||
}
|
||||
default:
|
||||
WARN("Unknown type %ld\n",(DWORD)rguid);
|
||||
WARN("Unknown type %p\n",rguid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ static HRESULT WINAPI SysKeyboardAImpl_GetProperty(
|
|||
TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
|
||||
ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
|
||||
if (!HIWORD(rguid)) {
|
||||
switch ((DWORD)rguid) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPDIPROPDWORD pd = (LPDIPROPDWORD)ph;
|
||||
|
||||
|
@ -387,7 +387,7 @@ static HRESULT WINAPI SysKeyboardAImpl_GetProperty(
|
|||
break;
|
||||
}
|
||||
default:
|
||||
WARN("Unknown type %ld\n",(DWORD)rguid);
|
||||
WARN("Unknown type %p\n",rguid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -597,7 +597,7 @@ static HRESULT WINAPI SysKeyboardAImpl_SetEventNotification(LPDIRECTINPUTDEVICE8
|
|||
HANDLE hnd) {
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
|
||||
TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
|
||||
TRACE("(this=%p,%p)\n",This,hnd);
|
||||
|
||||
This->hEvent = hnd;
|
||||
return DI_OK;
|
||||
|
@ -747,7 +747,7 @@ static HRESULT WINAPI SysKeyboardWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface
|
|||
return DI_OK;
|
||||
}
|
||||
|
||||
static IDirectInputDevice8AVtbl SysKeyboardAvt =
|
||||
static const IDirectInputDevice8AVtbl SysKeyboardAvt =
|
||||
{
|
||||
IDirectInputDevice2AImpl_QueryInterface,
|
||||
IDirectInputDevice2AImpl_AddRef,
|
||||
|
@ -789,7 +789,7 @@ static IDirectInputDevice8AVtbl SysKeyboardAvt =
|
|||
# define XCAST(fun) (void*)
|
||||
#endif
|
||||
|
||||
static IDirectInputDevice8WVtbl SysKeyboardWvt =
|
||||
static const IDirectInputDevice8WVtbl SysKeyboardWvt =
|
||||
{
|
||||
IDirectInputDevice2WImpl_QueryInterface,
|
||||
XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
|
||||
|
|
|
@ -95,8 +95,8 @@ static const DIDATAFORMAT Wine_InternalMouseFormat = {
|
|||
(LPDIOBJECTDATAFORMAT) Wine_InternalMouseObjectFormat
|
||||
};
|
||||
|
||||
static IDirectInputDevice8AVtbl SysMouseAvt;
|
||||
static IDirectInputDevice8WVtbl SysMouseWvt;
|
||||
static const IDirectInputDevice8AVtbl SysMouseAvt;
|
||||
static const IDirectInputDevice8WVtbl SysMouseWvt;
|
||||
|
||||
typedef struct SysMouseImpl SysMouseImpl;
|
||||
|
||||
|
@ -108,8 +108,8 @@ typedef enum {
|
|||
|
||||
struct SysMouseImpl
|
||||
{
|
||||
LPVOID lpVtbl;
|
||||
DWORD ref;
|
||||
const void *lpVtbl;
|
||||
LONG ref;
|
||||
GUID guid;
|
||||
|
||||
IDirectInputImpl *dinput;
|
||||
|
@ -241,7 +241,7 @@ static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINST
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static SysMouseImpl *alloc_device(REFGUID rguid, LPVOID mvt, IDirectInputImpl *dinput)
|
||||
static SysMouseImpl *alloc_device(REFGUID rguid, const void *mvt, IDirectInputImpl *dinput)
|
||||
{
|
||||
int offset_array[WINE_INTERNALMOUSE_NUM_OBJS] = {
|
||||
FIELD_OFFSET(Wine_InternalMouseData, lX),
|
||||
|
@ -363,7 +363,7 @@ static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
|
|||
{
|
||||
SysMouseImpl *This = (SysMouseImpl *)iface;
|
||||
|
||||
TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
|
||||
TRACE("(this=%p,%p,0x%08lx)\n",This,hwnd,dwflags);
|
||||
|
||||
if (TRACE_ON(dinput)) {
|
||||
TRACE(" cooperative level : ");
|
||||
|
@ -865,7 +865,7 @@ static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
|
||||
|
||||
if (!HIWORD(rguid)) {
|
||||
switch ((DWORD)rguid) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
|
||||
|
||||
|
@ -884,7 +884,7 @@ static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
|
||||
FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -908,7 +908,7 @@ static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
_dump_DIPROPHEADER(pdiph);
|
||||
|
||||
if (!HIWORD(rguid)) {
|
||||
switch ((DWORD)rguid) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
|
||||
|
||||
|
@ -943,7 +943,7 @@ static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|||
}
|
||||
|
||||
default:
|
||||
FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
|
||||
FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -960,7 +960,7 @@ static HRESULT WINAPI SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE8A i
|
|||
HANDLE hnd) {
|
||||
SysMouseImpl *This = (SysMouseImpl *)iface;
|
||||
|
||||
TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
|
||||
TRACE("(this=%p,%p)\n",This,hnd);
|
||||
|
||||
This->hEvent = hnd;
|
||||
|
||||
|
@ -1133,7 +1133,7 @@ static HRESULT WINAPI SysMouseWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, L
|
|||
}
|
||||
|
||||
|
||||
static IDirectInputDevice8AVtbl SysMouseAvt =
|
||||
static const IDirectInputDevice8AVtbl SysMouseAvt =
|
||||
{
|
||||
IDirectInputDevice2AImpl_QueryInterface,
|
||||
IDirectInputDevice2AImpl_AddRef,
|
||||
|
@ -1175,7 +1175,7 @@ static IDirectInputDevice8AVtbl SysMouseAvt =
|
|||
# define XCAST(fun) (void*)
|
||||
#endif
|
||||
|
||||
static IDirectInputDevice8WVtbl SysMouseWvt =
|
||||
static const IDirectInputDevice8WVtbl SysMouseWvt =
|
||||
{
|
||||
IDirectInputDevice2WImpl_QueryInterface,
|
||||
XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
|
||||
|
|
|
@ -530,7 +530,7 @@ static struct regsvr_interface const interface_list[] = {
|
|||
/***********************************************************************
|
||||
* DllRegisterServer (DINPUT.@)
|
||||
*/
|
||||
HRESULT WINAPI DINPUT_DllRegisterServer(void)
|
||||
HRESULT WINAPI DllRegisterServer(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -545,7 +545,7 @@ HRESULT WINAPI DINPUT_DllRegisterServer(void)
|
|||
/***********************************************************************
|
||||
* DllUnregisterServer (DINPUT.@)
|
||||
*/
|
||||
HRESULT WINAPI DINPUT_DllUnregisterServer(void)
|
||||
HRESULT WINAPI DllUnregisterServer(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
/*
|
||||
* Copyright 2001 Ove Kaaven
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define WINE_FILEDESCRIPTION_STR "Wine DirectInput"
|
||||
#define WINE_FILENAME_STR "dinput.dll"
|
||||
#define WINE_FILEVERSION 5,1,2600,881
|
||||
#define WINE_FILEVERSION_STR "5.1.2600.881"
|
||||
#define WINE_PRODUCTVERSION 5,1,2600,881
|
||||
#define WINE_PRODUCTVERSION_STR "5.1"
|
||||
|
||||
#include "wine/wine_common_ver.rc"
|
||||
/*
|
||||
* Copyright 2001 Ove Kaaven
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define WINE_FILEDESCRIPTION_STR "Wine DirectInput"
|
||||
#define WINE_FILENAME_STR "dinput.dll"
|
||||
#define WINE_FILEVERSION 5,1,2600,881
|
||||
#define WINE_FILEVERSION_STR "5.1.2600.881"
|
||||
#define WINE_PRODUCTVERSION 5,1,2600,881
|
||||
#define WINE_PRODUCTVERSION_STR "5.1"
|
||||
|
||||
#include "wine/wine_common_ver.rc"
|
||||
|
|
Loading…
Reference in a new issue