mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 21:06:17 +00:00
- sync dinput with wine
svn path=/trunk/; revision=39290
This commit is contained in:
parent
cfad1c5307
commit
4e5afc5ce8
15 changed files with 3483 additions and 4011 deletions
|
@ -13,7 +13,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -74,7 +74,7 @@ const DIDATAFORMAT c_dfDIJoystick = {
|
|||
sizeof(DIDATAFORMAT),
|
||||
sizeof(DIOBJECTDATAFORMAT),
|
||||
DIDF_ABSAXIS,
|
||||
sizeof(DIJOYSTATE2),
|
||||
sizeof(DIJOYSTATE),
|
||||
numObjects(dfDIJoystick),
|
||||
(LPDIOBJECTDATAFORMAT)dfDIJoystick
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_DLLS_DINPUT_DINPUTDEVICE_PRIVATE_H
|
||||
|
@ -25,78 +25,98 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "dinput.h"
|
||||
#include "wine/list.h"
|
||||
#include "dinput_private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int size;
|
||||
int offset_in;
|
||||
int offset_out;
|
||||
int value;
|
||||
} DataTransform;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int size;
|
||||
int internal_format_size;
|
||||
DataTransform *dt;
|
||||
|
||||
int *offsets; /* object offsets */
|
||||
LPDIDATAFORMAT wine_df; /* wine internal data format */
|
||||
LPDIDATAFORMAT user_df; /* user defined data format */
|
||||
} DataFormat;
|
||||
|
||||
/* Device implementation */
|
||||
typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl;
|
||||
struct IDirectInputDevice2AImpl
|
||||
{
|
||||
const IDirectInputDevice2AVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
GUID guid;
|
||||
const void *lpVtbl;
|
||||
LONG ref;
|
||||
GUID guid;
|
||||
CRITICAL_SECTION crit;
|
||||
IDirectInputImpl *dinput;
|
||||
struct list entry; /* entry into IDirectInput devices list */
|
||||
HANDLE hEvent;
|
||||
DWORD dwCoopLevel;
|
||||
HWND win;
|
||||
int acquired;
|
||||
DI_EVENT_PROC event_proc; /* function to receive mouse & keyboard events */
|
||||
|
||||
LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. */
|
||||
int queue_len; /* size of the queue - set in 'SetProperty' */
|
||||
int queue_head; /* position to write new event into queue */
|
||||
int queue_tail; /* next event to read from queue */
|
||||
BOOL overflow; /* return DI_BUFFEROVERFLOW in 'GetDeviceData' */
|
||||
|
||||
DataFormat data_format; /* user data format and wine to user format converter */
|
||||
};
|
||||
|
||||
extern BOOL get_app_key(HKEY*, HKEY*);
|
||||
extern DWORD get_config_key(HKEY, HKEY, const char*, char*, DWORD);
|
||||
|
||||
/* Routines to do DataFormat / WineFormat conversions */
|
||||
typedef struct {
|
||||
int size;
|
||||
int offset_in;
|
||||
int offset_out;
|
||||
int value;
|
||||
} DataTransform;
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
int internal_format_size;
|
||||
DataTransform *dt;
|
||||
} DataFormat;
|
||||
extern void fill_DataFormat(void *out, const void *in, DataFormat *df) ;
|
||||
extern DataFormat *create_DataFormat(const DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) ;
|
||||
extern void fill_DataFormat(void *out, DWORD size, const void *in, const DataFormat *df) ;
|
||||
extern void release_DataFormat(DataFormat *df) ;
|
||||
extern void queue_event(LPDIRECTINPUTDEVICE8A iface, int ofs, DWORD data, DWORD time, DWORD seq);
|
||||
/* Helper functions to work with data format */
|
||||
extern int id_to_object(LPCDIDATAFORMAT df, int id);
|
||||
extern int id_to_offset(const DataFormat *df, int id);
|
||||
extern int find_property(const DataFormat *df, LPCDIPROPHEADER ph);
|
||||
|
||||
/* Used to fill events in the queue */
|
||||
#define GEN_EVENT(offset,data,xtime,seq) \
|
||||
{ \
|
||||
/* If queue_len > 0, queuing is requested -> TRACE the event queued */ \
|
||||
if (This->queue_len > 0) { \
|
||||
int nq; \
|
||||
TRACE(" queueing %d at offset %d (queue head %d / size %d)\n", \
|
||||
(int) (data), (int) (offset), \
|
||||
(int) (This->queue_head), (int) (This->queue_len)); \
|
||||
\
|
||||
nq = This->queue_head+1; \
|
||||
while (nq >= This->queue_len) nq -= This->queue_len; \
|
||||
if ((offset >= 0) && (nq != This->queue_tail)) { \
|
||||
This->data_queue[This->queue_head].dwOfs = offset; \
|
||||
This->data_queue[This->queue_head].dwData = data; \
|
||||
This->data_queue[This->queue_head].dwTimeStamp = xtime; \
|
||||
This->data_queue[This->queue_head].dwSequence = seq; \
|
||||
This->queue_head = nq; \
|
||||
} else \
|
||||
This->overflow = TRUE; \
|
||||
} \
|
||||
}
|
||||
/* Common joystick stuff */
|
||||
typedef struct
|
||||
{
|
||||
LONG lDevMin;
|
||||
LONG lDevMax;
|
||||
LONG lMin;
|
||||
LONG lMax;
|
||||
LONG lDeadZone;
|
||||
LONG lSaturation;
|
||||
} ObjProps;
|
||||
|
||||
/**
|
||||
* Callback Data used by specific callback
|
||||
* for EnumObject on 'W' interfaces
|
||||
*/
|
||||
typedef struct {
|
||||
LPDIENUMDEVICEOBJECTSCALLBACKW lpCallBack;
|
||||
LPVOID lpvRef;
|
||||
} device_enumobjects_AtoWcb_data;
|
||||
extern DWORD joystick_map_pov(POINTL *p);
|
||||
extern LONG joystick_map_axis(ObjProps *props, int val);
|
||||
|
||||
extern BOOL DIEnumDevicesCallbackAtoW(LPCDIDEVICEOBJECTINSTANCEA, LPVOID);
|
||||
typedef struct
|
||||
{
|
||||
struct list entry;
|
||||
LPDIRECTINPUTEFFECT ref;
|
||||
} effect_list_item;
|
||||
|
||||
extern const GUID DInput_Wine_Keyboard_GUID;
|
||||
extern const GUID DInput_Wine_Mouse_GUID;
|
||||
|
||||
/* Various debug tools */
|
||||
extern void _dump_cooperativelevel_DI(DWORD dwFlags) ;
|
||||
extern void _dump_EnumObjects_flags(DWORD dwFlags) ;
|
||||
extern void _dump_DIPROPHEADER(LPCDIPROPHEADER diph) ;
|
||||
extern void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) ;
|
||||
extern void _dump_OBJECTINSTANCEW(DIDEVICEOBJECTINSTANCEW *ddoi) ;
|
||||
extern void _dump_OBJECTINSTANCEA(const DIDEVICEOBJECTINSTANCEA *ddoi) ;
|
||||
extern void _dump_OBJECTINSTANCEW(const DIDEVICEOBJECTINSTANCEW *ddoi) ;
|
||||
extern void _dump_DIDATAFORMAT(const DIDATAFORMAT *df) ;
|
||||
extern const char *_dump_dinput_GUID(const GUID *guid) ;
|
||||
|
||||
/* And the stubs */
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_Acquire(LPDIRECTINPUTDEVICE8A iface);
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface);
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
|
||||
LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df ) ;
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
|
||||
|
@ -118,25 +138,19 @@ extern HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(
|
|||
LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
|
||||
LPVOID lpvRef,
|
||||
DWORD dwFlags) ;
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
|
||||
LPDIRECTINPUTDEVICE8A iface,
|
||||
REFGUID rguid,
|
||||
LPDIPROPHEADER pdiph) ;
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph);
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPCDIPROPHEADER pdiph);
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
|
||||
LPDIRECTINPUTDEVICE8A iface,
|
||||
LPDIDEVICEOBJECTINSTANCEA pdidoi,
|
||||
DWORD dwObj,
|
||||
DWORD dwHow) ;
|
||||
extern HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
|
||||
extern HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
|
||||
LPDIDEVICEOBJECTINSTANCEW pdidoi,
|
||||
DWORD dwObj,
|
||||
DWORD dwHow);
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
|
||||
LPDIRECTINPUTDEVICE8A iface,
|
||||
LPDIDEVICEINSTANCEA pdidi) ;
|
||||
extern HRESULT WINAPI IDirectInputDevice2WImpl_GetDeviceInfo(
|
||||
LPDIRECTINPUTDEVICE8W iface,
|
||||
LPDIDEVICEINSTANCEW pdidi) ;
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,
|
||||
DWORD dodsize, LPDIDEVICEOBJECTDATA dod, LPDWORD entries, DWORD flags);
|
||||
extern HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
|
||||
LPDIRECTINPUTDEVICE8A iface,
|
||||
HWND hwndOwner,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<module name="dinput" type="win32dll" baseaddress="${BASEADDRESS_DINPUT}" installbase="system32" installname="dinput.dll" unicode="yes">
|
||||
<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
|
||||
<importlibrary definition="dinput.spec" />
|
||||
<define name="_WIN32_WINNT">0x600</define>
|
||||
<include base="dinput">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<library>wine</library>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H
|
||||
|
@ -24,18 +24,25 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "dinput.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
/* Implementation specification */
|
||||
typedef struct IDirectInputImpl IDirectInputImpl;
|
||||
struct IDirectInputImpl
|
||||
{
|
||||
const void *lpVtbl;
|
||||
LONG ref;
|
||||
const IDirectInput7AVtbl *lpVtbl;
|
||||
const IDirectInput7WVtbl *lpVtbl7w;
|
||||
const IDirectInput8AVtbl *lpVtbl8a;
|
||||
const IDirectInput8WVtbl *lpVtbl8w;
|
||||
|
||||
/* Used to have an unique sequence number for all the events */
|
||||
DWORD evsequence;
|
||||
LONG ref;
|
||||
|
||||
DWORD dwVersion;
|
||||
CRITICAL_SECTION crit;
|
||||
struct list entry; /* entry into list of all IDirectInputs */
|
||||
|
||||
DWORD evsequence; /* unique sequence number for events */
|
||||
DWORD dwVersion; /* direct input version number */
|
||||
struct list devices_list; /* list of all created dinput devices */
|
||||
};
|
||||
|
||||
/* Function called by all devices that Wine supports */
|
||||
|
@ -52,6 +59,9 @@ extern const struct dinput_device keyboard_device;
|
|||
extern const struct dinput_device joystick_linux_device;
|
||||
extern const struct dinput_device joystick_linuxinput_device;
|
||||
|
||||
extern HINSTANCE DINPUT_instance;
|
||||
extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8A);
|
||||
typedef void (*DI_EVENT_PROC)(LPDIRECTINPUTDEVICE8A, WPARAM, LPARAM);
|
||||
|
||||
extern void _dump_diactionformatA(LPDIACTIONFORMATA);
|
||||
|
||||
#endif /* __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@ -27,6 +27,7 @@
|
|||
#include <string.h>
|
||||
#ifdef HAVE_LINUX_INPUT_H
|
||||
# include <linux/input.h>
|
||||
# undef SW_MAX
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
|
@ -52,11 +53,10 @@ struct LinuxInputEffectImpl
|
|||
LONG ref;
|
||||
GUID guid;
|
||||
|
||||
/* Effect data */
|
||||
struct ff_effect effect;
|
||||
|
||||
/* Parent device */
|
||||
int* fd;
|
||||
struct ff_effect effect; /* Effect data */
|
||||
int gain; /* Effect gain */
|
||||
int* fd; /* Parent device */
|
||||
struct list *entry; /* Entry into the parent's list of effects */
|
||||
};
|
||||
|
||||
|
||||
|
@ -91,7 +91,7 @@ static DWORD _typeFromGUID(REFGUID guid)
|
|||
|
||||
|
||||
/******************************************************************************
|
||||
* DirectInputEffect debug helpers
|
||||
* DirectInputEffect debug helpers
|
||||
*/
|
||||
|
||||
static void _dump_DIEFFECT_flags(DWORD dwFlags)
|
||||
|
@ -112,59 +112,58 @@ static void _dump_DIEFFECT_flags(DWORD dwFlags)
|
|||
};
|
||||
for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++)
|
||||
if (flags[i].mask & dwFlags)
|
||||
DPRINTF("%s ", flags[i].name);
|
||||
DPRINTF("\n");
|
||||
}
|
||||
TRACE("%s ", flags[i].name);
|
||||
TRACE("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void _dump_DIENVELOPE(LPDIENVELOPE env)
|
||||
static void _dump_DIENVELOPE(LPCDIENVELOPE env)
|
||||
{
|
||||
if (env->dwSize != sizeof(DIENVELOPE)) {
|
||||
WARN("Non-standard DIENVELOPE structure size (%ld instead of %d).\n",
|
||||
env->dwSize, sizeof(DIENVELOPE));
|
||||
WARN("Non-standard DIENVELOPE structure size %d.\n", env->dwSize);
|
||||
}
|
||||
TRACE("Envelope has attack (level: %ld time: %ld), fade (level: %ld time: %ld)\n",
|
||||
TRACE("Envelope has attack (level: %d time: %d), fade (level: %d time: %d)\n",
|
||||
env->dwAttackLevel, env->dwAttackTime, env->dwFadeLevel, env->dwFadeTime);
|
||||
}
|
||||
|
||||
static void _dump_DICONSTANTFORCE(LPCDICONSTANTFORCE frc)
|
||||
{
|
||||
TRACE("Constant force has magnitude %d\n", frc->lMagnitude);
|
||||
}
|
||||
|
||||
static void _dump_DICONSTANTFORCE(LPDICONSTANTFORCE frc)
|
||||
static void _dump_DIPERIODIC(LPCDIPERIODIC 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",
|
||||
TRACE("Periodic force has magnitude %d, offset %d, phase %d, period %d\n",
|
||||
frc->dwMagnitude, frc->lOffset, frc->dwPhase, frc->dwPeriod);
|
||||
}
|
||||
|
||||
static void _dump_DIRAMPFORCE(LPDIRAMPFORCE frc)
|
||||
static void _dump_DIRAMPFORCE(LPCDIRAMPFORCE frc)
|
||||
{
|
||||
TRACE("Ramp force has start %ld, end %ld\n",
|
||||
TRACE("Ramp force has start %d, end %d\n",
|
||||
frc->lStart, frc->lEnd);
|
||||
}
|
||||
|
||||
static void _dump_DICONDITION(LPDICONDITION frc)
|
||||
static void _dump_DICONDITION(LPCDICONDITION frc)
|
||||
{
|
||||
TRACE("Condition has offset %ld, pos/neg coefficients %ld and %ld, pos/neg saturations %ld and %ld, deadband %ld\n",
|
||||
TRACE("Condition has offset %d, pos/neg coefficients %d and %d, pos/neg saturations %d and %d, deadband %d\n",
|
||||
frc->lOffset, frc->lPositiveCoefficient, frc->lNegativeCoefficient,
|
||||
frc->dwPositiveSaturation, frc->dwNegativeSaturation, frc->lDeadBand);
|
||||
}
|
||||
|
||||
static void _dump_DICUSTOMFORCE(LPDICUSTOMFORCE frc)
|
||||
static void _dump_DICUSTOMFORCE(LPCDICUSTOMFORCE frc)
|
||||
{
|
||||
unsigned int i;
|
||||
TRACE("Custom force uses %ld channels, sample period %ld. Has %ld samples at %p.\n",
|
||||
TRACE("Custom force uses %d channels, sample period %d. Has %d samples at %p.\n",
|
||||
frc->cChannels, frc->dwSamplePeriod, frc->cSamples, frc->rglForceData);
|
||||
if (frc->cSamples % frc->cChannels != 0)
|
||||
WARN("Custom force has a non-integral samples-per-channel count!\n");
|
||||
if (TRACE_ON(dinput)) {
|
||||
DPRINTF("Custom force data (time aligned, axes in order):\n");
|
||||
TRACE("Custom force data (time aligned, axes in order):\n");
|
||||
for (i = 1; i <= frc->cSamples; ++i) {
|
||||
DPRINTF("%ld ", frc->rglForceData[i]);
|
||||
TRACE("%d ", frc->rglForceData[i]);
|
||||
if (i % frc->cChannels == 0)
|
||||
DPRINTF("\n");
|
||||
}
|
||||
TRACE("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,43 +173,42 @@ static void _dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid)
|
|||
DWORD type = _typeFromGUID(guid);
|
||||
|
||||
TRACE("Dumping DIEFFECT structure:\n");
|
||||
TRACE(" - dwSize: %ld\n", eff->dwSize);
|
||||
TRACE(" - dwSize: %d\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));
|
||||
WARN("Non-standard DIEFFECT structure size %d\n", eff->dwSize);
|
||||
}
|
||||
TRACE(" - dwFlags: %ld\n", eff->dwFlags);
|
||||
TRACE(" - dwFlags: %d\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);
|
||||
_dump_DIEFFECT_flags(eff->dwFlags);
|
||||
TRACE(" - dwDuration: %d\n", eff->dwDuration);
|
||||
TRACE(" - dwGain: %d\n", eff->dwGain);
|
||||
if (eff->dwGain > 10000)
|
||||
WARN("dwGain is out of range (>10,000)\n");
|
||||
TRACE(" - dwTriggerButton: %d\n", eff->dwTriggerButton);
|
||||
TRACE(" - dwTriggerRepeatInterval: %d\n", eff->dwTriggerRepeatInterval);
|
||||
TRACE(" - cAxes: %d\n", eff->cAxes);
|
||||
TRACE(" - rgdwAxes: %p\n", eff->rgdwAxes);
|
||||
if (TRACE_ON(dinput)) {
|
||||
TRACE(" ");
|
||||
if (TRACE_ON(dinput) && eff->rgdwAxes) {
|
||||
TRACE(" ");
|
||||
for (i = 0; i < eff->cAxes; ++i)
|
||||
DPRINTF("%ld ", eff->rgdwAxes[i]);
|
||||
DPRINTF("\n");
|
||||
TRACE("%d ", eff->rgdwAxes[i]);
|
||||
TRACE("\n");
|
||||
}
|
||||
TRACE(" - rglDirection: %p\n", eff->rglDirection);
|
||||
TRACE(" - lpEnvelope: %p\n", eff->lpEnvelope);
|
||||
TRACE(" - cbTypeSpecificParams: %ld\n", eff->cbTypeSpecificParams);
|
||||
TRACE(" - cbTypeSpecificParams: %d\n", eff->cbTypeSpecificParams);
|
||||
TRACE(" - lpvTypeSpecificParams: %p\n", eff->lpvTypeSpecificParams);
|
||||
if (eff->dwSize > sizeof(DIEFFECT_DX5))
|
||||
TRACE(" - dwStartDelay: %ld\n", eff->dwStartDelay);
|
||||
TRACE(" - dwStartDelay: %d\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");
|
||||
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) {
|
||||
} 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 {
|
||||
|
@ -222,7 +220,7 @@ static void _dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid)
|
|||
} else {
|
||||
_dump_DIRAMPFORCE(eff->lpvTypeSpecificParams);
|
||||
}
|
||||
} else if (type == DIEFT_CONDITION) {
|
||||
} 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 {
|
||||
|
@ -239,7 +237,7 @@ static void _dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid)
|
|||
|
||||
|
||||
/******************************************************************************
|
||||
* LinuxInputEffectImpl
|
||||
* LinuxInputEffectImpl
|
||||
*/
|
||||
|
||||
static ULONG WINAPI LinuxInputEffectImpl_AddRef(
|
||||
|
@ -260,7 +258,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_Download(
|
|||
if (errno == ENOMEM) {
|
||||
return DIERR_DEVICEFULL;
|
||||
} else {
|
||||
FIXME("Could not upload effect. Assuming a disconnected device.\n");
|
||||
FIXME("Could not upload effect. Assuming a disconnected device %d \"%s\".\n", *This->fd, strerror(errno));
|
||||
return DIERR_INPUTLOST;
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +270,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_Escape(
|
|||
LPDIRECTINPUTEFFECT iface,
|
||||
LPDIEFFESCAPE pesc)
|
||||
{
|
||||
WARN("(this=%p,%p): invalid: no hardware-specific escape codes in this"
|
||||
WARN("(this=%p,%p): invalid: no hardware-specific escape codes in this"
|
||||
" driver!\n", iface, pesc);
|
||||
|
||||
return DI_OK;
|
||||
|
@ -287,7 +285,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_GetEffectGuid(
|
|||
TRACE("(this=%p,%p)\n", This, pguid);
|
||||
|
||||
pguid = &This->guid;
|
||||
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
|
@ -314,7 +312,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_GetParameters(
|
|||
{
|
||||
HRESULT diErr = DI_OK;
|
||||
LinuxInputEffectImpl *This = (LinuxInputEffectImpl *)iface;
|
||||
TRACE("(this=%p,%p,%ld)\n", This, peff, dwFlags);
|
||||
TRACE("(this=%p,%p,%d)\n", This, peff, dwFlags);
|
||||
|
||||
/* Major conversion factors are:
|
||||
* times: millisecond (linux) -> microsecond (windows) (x * 1000)
|
||||
|
@ -326,7 +324,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_GetParameters(
|
|||
if (dwFlags & DIEP_AXES) {
|
||||
if (peff->cAxes < 2 /* linuxinput effects always use 2 axes, x and y */)
|
||||
diErr = DIERR_MOREDATA;
|
||||
peff->cAxes = 2;
|
||||
peff->cAxes = 2;
|
||||
if (diErr)
|
||||
return diErr;
|
||||
else {
|
||||
|
@ -334,11 +332,11 @@ static HRESULT WINAPI LinuxInputEffectImpl_GetParameters(
|
|||
peff->rgdwAxes[1] = DIJOFS_Y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dwFlags & DIEP_DIRECTION) {
|
||||
if (peff->cAxes < 2)
|
||||
diErr = DIERR_MOREDATA;
|
||||
peff->cAxes = 2;
|
||||
peff->cAxes = 2;
|
||||
if (diErr)
|
||||
return diErr;
|
||||
else {
|
||||
|
@ -373,7 +371,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_GetParameters(
|
|||
peff->lpEnvelope = NULL;
|
||||
} else if (peff->lpEnvelope == NULL) {
|
||||
return DIERR_INVALIDPARAM;
|
||||
} else {
|
||||
} else {
|
||||
peff->lpEnvelope->dwAttackLevel = (env->attack_level / 33) * 10;
|
||||
peff->lpEnvelope->dwAttackTime = env->attack_length * 1000;
|
||||
peff->lpEnvelope->dwFadeLevel = (env->fade_level / 33) * 10;
|
||||
|
@ -382,9 +380,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_GetParameters(
|
|||
}
|
||||
|
||||
if (dwFlags & DIEP_GAIN) {
|
||||
/* the linux input ff driver apparently has no support
|
||||
* for setting the device's gain. */
|
||||
peff->dwGain = DI_FFNOMINALMAX;
|
||||
peff->dwGain = This->gain * 10000 / 0xFFFF;
|
||||
}
|
||||
|
||||
if (dwFlags & DIEP_SAMPLEPERIOD) {
|
||||
|
@ -407,14 +403,14 @@ static HRESULT WINAPI LinuxInputEffectImpl_GetParameters(
|
|||
}
|
||||
|
||||
if (dwFlags & DIEP_TYPESPECIFICPARAMS) {
|
||||
int expectedsize = 0;
|
||||
DWORD expectedsize = 0;
|
||||
if (This->effect.type == FF_PERIODIC) {
|
||||
expectedsize = sizeof(DIPERIODIC);
|
||||
} else if (This->effect.type == FF_CONSTANT) {
|
||||
expectedsize = sizeof(DICONSTANTFORCE);
|
||||
} else if (This->effect.type == FF_SPRING
|
||||
|| This->effect.type == FF_FRICTION
|
||||
|| This->effect.type == FF_INERTIA
|
||||
} 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) {
|
||||
|
@ -427,35 +423,35 @@ static HRESULT WINAPI LinuxInputEffectImpl_GetParameters(
|
|||
return diErr;
|
||||
else {
|
||||
if (This->effect.type == FF_PERIODIC) {
|
||||
LPDIPERIODIC tsp = (LPDIPERIODIC)(peff->lpvTypeSpecificParams);
|
||||
LPDIPERIODIC tsp = peff->lpvTypeSpecificParams;
|
||||
tsp->dwMagnitude = (This->effect.u.periodic.magnitude / 33) * 10;
|
||||
tsp->lOffset = (This->effect.u.periodic.offset / 33) * 10;
|
||||
tsp->dwPhase = (This->effect.u.periodic.phase / 33) * 36;
|
||||
tsp->dwPeriod = (This->effect.u.periodic.period * 1000);
|
||||
} else if (This->effect.type == FF_CONSTANT) {
|
||||
LPDICONSTANTFORCE tsp = (LPDICONSTANTFORCE)(peff->lpvTypeSpecificParams);
|
||||
LPDICONSTANTFORCE tsp = peff->lpvTypeSpecificParams;
|
||||
tsp->lMagnitude = (This->effect.u.constant.level / 33) * 10;
|
||||
} else if (This->effect.type == FF_SPRING
|
||||
|| This->effect.type == FF_FRICTION
|
||||
|| This->effect.type == FF_INERTIA
|
||||
} 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);
|
||||
LPDICONDITION tsp = peff->lpvTypeSpecificParams;
|
||||
int i;
|
||||
for (i = 0; i < 2; ++i) {
|
||||
tsp[i].lOffset = (This->effect.u.condition[i].center / 33) * 10;
|
||||
tsp[i].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].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);
|
||||
LPDIRAMPFORCE tsp = peff->lpvTypeSpecificParams;
|
||||
tsp->lStart = (This->effect.u.ramp.start_level / 33) * 10;
|
||||
tsp->lEnd = (This->effect.u.ramp.end_level / 33) * 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return diErr;
|
||||
}
|
||||
|
@ -466,7 +462,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_Initialize(
|
|||
DWORD dwVersion,
|
||||
REFGUID rguid)
|
||||
{
|
||||
FIXME("(this=%p,%p,%ld,%s): stub!\n",
|
||||
FIXME("(this=%p,%p,%d,%s): stub!\n",
|
||||
iface, hinst, dwVersion, debugstr_guid(rguid));
|
||||
|
||||
return DI_OK;
|
||||
|
@ -500,7 +496,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_Start(
|
|||
struct input_event event;
|
||||
LinuxInputEffectImpl* This = (LinuxInputEffectImpl*)iface;
|
||||
|
||||
TRACE("(this=%p,%ld,%ld)\n", This, dwIterations, dwFlags);
|
||||
TRACE("(this=%p,%d,%d)\n", This, dwIterations, dwFlags);
|
||||
|
||||
if (!(dwFlags & DIES_NODOWNLOAD)) {
|
||||
/* Download the effect if necessary */
|
||||
|
@ -516,6 +512,12 @@ static HRESULT WINAPI LinuxInputEffectImpl_Start(
|
|||
}
|
||||
|
||||
event.type = EV_FF;
|
||||
|
||||
event.code = FF_GAIN;
|
||||
event.value = This->gain;
|
||||
if (write(*(This->fd), &event, sizeof(event)) == -1)
|
||||
FIXME("Failed setting gain. Error: %d \"%s\".\n", errno, strerror(errno));
|
||||
|
||||
event.code = This->effect.id;
|
||||
event.value = dwIterations;
|
||||
if (write(*(This->fd), &event, sizeof(event)) == -1) {
|
||||
|
@ -530,16 +532,16 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
|
|||
LPDIRECTINPUTEFFECT iface,
|
||||
LPCDIEFFECT peff,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
LinuxInputEffectImpl* This = (LinuxInputEffectImpl*)iface;
|
||||
{
|
||||
LinuxInputEffectImpl* This = (LinuxInputEffectImpl*)iface;
|
||||
DWORD type = _typeFromGUID(&This->guid);
|
||||
HRESULT retval = DI_OK;
|
||||
|
||||
TRACE("(this=%p,%p,%ld)\n", This, peff, dwFlags);
|
||||
TRACE("(this=%p,%p,%d)\n", This, peff, dwFlags);
|
||||
|
||||
_dump_DIEFFECT(peff, &This->guid);
|
||||
|
||||
if ((dwFlags & !DIEP_NORESTART & !DIEP_NODOWNLOAD & !DIEP_START) == 0) {
|
||||
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 |
|
||||
|
@ -556,7 +558,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
|
|||
|
||||
/* 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). */
|
||||
* axis (left), linux has it along the y axis (down). */
|
||||
if (dwFlags & DIEP_DIRECTION) {
|
||||
if (peff->cAxes == 1) {
|
||||
if (peff->dwFlags & DIEFF_CARTESIAN) {
|
||||
|
@ -601,11 +603,11 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
|
|||
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;
|
||||
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 */
|
||||
* note that length can never be zero, so we set it to something minuscule */
|
||||
if (env) {
|
||||
env->attack_length = 0x10;
|
||||
env->attack_level = 0x7FFF;
|
||||
|
@ -626,7 +628,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
|
|||
/* 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");
|
||||
This->gain = 0xFFFF * peff->dwGain / 10000;
|
||||
|
||||
if (dwFlags & DIEP_SAMPLEPERIOD)
|
||||
TRACE("Sample period requested but no sample period functionality present.\n");
|
||||
|
@ -652,7 +654,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
|
|||
LPCDIPERIODIC tsp;
|
||||
if (peff->cbTypeSpecificParams != sizeof(DIPERIODIC))
|
||||
return DIERR_INVALIDPARAM;
|
||||
tsp = (LPCDIPERIODIC)(peff->lpvTypeSpecificParams);
|
||||
tsp = 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) */
|
||||
|
@ -661,17 +663,17 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
|
|||
LPCDICONSTANTFORCE tsp;
|
||||
if (peff->cbTypeSpecificParams != sizeof(DICONSTANTFORCE))
|
||||
return DIERR_INVALIDPARAM;
|
||||
tsp = (LPCDICONSTANTFORCE)(peff->lpvTypeSpecificParams);
|
||||
This->effect.u.constant.level = (tsp->lMagnitude / 10) * 32;
|
||||
tsp = peff->lpvTypeSpecificParams;
|
||||
This->effect.u.constant.level = (max(min(tsp->lMagnitude, 10000), -10000) / 10) * 32;
|
||||
} else if (type == DIEFT_RAMPFORCE) {
|
||||
LPCDIRAMPFORCE tsp;
|
||||
if (peff->cbTypeSpecificParams != sizeof(DIRAMPFORCE))
|
||||
return DIERR_INVALIDPARAM;
|
||||
tsp = (LPCDIRAMPFORCE)(peff->lpvTypeSpecificParams);
|
||||
tsp = 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);
|
||||
LPCDICONDITION tsp = 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. */
|
||||
|
@ -682,7 +684,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
|
|||
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].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);
|
||||
|
@ -702,7 +704,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
|
|||
return DIERR_INVALIDPARAM;
|
||||
}
|
||||
} else {
|
||||
FIXME("Custom force types are not supported\n");
|
||||
FIXME("Custom force types are not supported\n");
|
||||
return DIERR_INVALIDPARAM;
|
||||
}
|
||||
}
|
||||
|
@ -719,20 +721,9 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters(
|
|||
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)
|
||||
|
@ -767,6 +758,22 @@ static HRESULT WINAPI LinuxInputEffectImpl_Unload(
|
|||
return DI_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI LinuxInputEffectImpl_Release(LPDIRECTINPUTEFFECT iface)
|
||||
{
|
||||
LinuxInputEffectImpl *This = (LinuxInputEffectImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&(This->ref));
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
LinuxInputEffectImpl_Stop(iface);
|
||||
LinuxInputEffectImpl_Unload(iface);
|
||||
list_remove(This->entry);
|
||||
HeapFree(GetProcessHeap(), 0, LIST_ENTRY(This->entry, effect_list_item, entry));
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* LinuxInputEffect
|
||||
*/
|
||||
|
@ -774,20 +781,22 @@ static HRESULT WINAPI LinuxInputEffectImpl_Unload(
|
|||
HRESULT linuxinput_create_effect(
|
||||
int* fd,
|
||||
REFGUID rguid,
|
||||
struct list *parent_list_entry,
|
||||
LPDIRECTINPUTEFFECT* peff)
|
||||
{
|
||||
LinuxInputEffectImpl* newEffect = HeapAlloc(GetProcessHeap(),
|
||||
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->guid = *rguid;
|
||||
newEffect->fd = fd;
|
||||
newEffect->gain = 0xFFFF;
|
||||
|
||||
/* set the type. this cannot be changed over the effect's life. */
|
||||
switch (type) {
|
||||
case DIEFT_PERIODIC:
|
||||
case DIEFT_PERIODIC:
|
||||
newEffect->effect.type = FF_PERIODIC;
|
||||
if (IsEqualGUID(rguid, &GUID_Sine)) {
|
||||
newEffect->effect.u.periodic.waveform = FF_SINE;
|
||||
|
@ -801,13 +810,13 @@ HRESULT linuxinput_create_effect(
|
|||
newEffect->effect.u.periodic.waveform = FF_SAW_DOWN;
|
||||
}
|
||||
break;
|
||||
case DIEFT_CONSTANTFORCE:
|
||||
case DIEFT_CONSTANTFORCE:
|
||||
newEffect->effect.type = FF_CONSTANT;
|
||||
break;
|
||||
case DIEFT_RAMPFORCE:
|
||||
case DIEFT_RAMPFORCE:
|
||||
newEffect->effect.type = FF_RAMP;
|
||||
break;
|
||||
case DIEFT_CONDITION:
|
||||
case DIEFT_CONDITION:
|
||||
if (IsEqualGUID(rguid, &GUID_Spring)) {
|
||||
newEffect->effect.type = FF_SPRING;
|
||||
} else if (IsEqualGUID(rguid, &GUID_Friction)) {
|
||||
|
@ -823,7 +832,7 @@ HRESULT linuxinput_create_effect(
|
|||
HeapFree(GetProcessHeap(), 0, newEffect);
|
||||
return DIERR_INVALIDPARAM;
|
||||
default:
|
||||
FIXME("Unknown force type.\n");
|
||||
FIXME("Unknown force type 0x%x.\n", type);
|
||||
HeapFree(GetProcessHeap(), 0, newEffect);
|
||||
return DIERR_INVALIDPARAM;
|
||||
}
|
||||
|
@ -831,9 +840,11 @@ HRESULT linuxinput_create_effect(
|
|||
/* mark as non-uploaded */
|
||||
newEffect->effect.id = -1;
|
||||
|
||||
*peff = (LPDIRECTINPUTEFFECT)newEffect;
|
||||
newEffect->entry = parent_list_entry;
|
||||
|
||||
TRACE("Creating linux input system effect (%p) with guid %s\n",
|
||||
*peff = (LPDIRECTINPUTEFFECT)newEffect;
|
||||
|
||||
TRACE("Creating linux input system effect (%p) with guid %s\n",
|
||||
*peff, _dump_dinput_GUID(rguid));
|
||||
|
||||
return DI_OK;
|
||||
|
@ -846,29 +857,29 @@ HRESULT linuxinput_get_info_A(
|
|||
{
|
||||
DWORD type = _typeFromGUID(rguid);
|
||||
|
||||
TRACE("(%d, %s, %p) type=%ld\n", fd, _dump_dinput_GUID(rguid), info, type);
|
||||
TRACE("(%d, %s, %p) type=%d\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;
|
||||
|
||||
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
|
||||
info->dwEffType |= DIEFT_DEADBAND | DIEFT_FFATTACK | DIEFT_FFFADE
|
||||
| DIEFT_POSNEGCOEFFICIENTS | DIEFT_POSNEGSATURATION
|
||||
| DIEFT_SATURATION | DIEFT_STARTDELAY;
|
||||
| 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));
|
||||
strcpy(info->tszName, _dump_dinput_GUID(rguid));
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
@ -880,7 +891,7 @@ HRESULT linuxinput_get_info_W(
|
|||
{
|
||||
DWORD type = _typeFromGUID(rguid);
|
||||
|
||||
TRACE("(%d, %s, %p) type=%ld\n", fd, _dump_dinput_GUID(rguid), info, type);
|
||||
TRACE("(%d, %s, %p) type=%d\n", fd, _dump_dinput_GUID(rguid), info, type);
|
||||
|
||||
if (!info) return E_POINTER;
|
||||
|
||||
|
@ -895,15 +906,15 @@ HRESULT linuxinput_get_info_W(
|
|||
* ignore parameters they claim to support anyway */
|
||||
info->dwEffType |= DIEFT_DEADBAND | DIEFT_FFATTACK | DIEFT_FFFADE
|
||||
| DIEFT_POSNEGCOEFFICIENTS | DIEFT_POSNEGSATURATION
|
||||
| DIEFT_SATURATION | DIEFT_STARTDELAY;
|
||||
| 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);
|
||||
MultiByteToWideChar(CP_ACP, 0, _dump_dinput_GUID(rguid), -1,
|
||||
info->tszName, MAX_PATH);
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -17,7 +17,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@ -46,122 +46,79 @@ static const IDirectInputDevice8WVtbl SysKeyboardWvt;
|
|||
typedef struct SysKeyboardImpl SysKeyboardImpl;
|
||||
struct SysKeyboardImpl
|
||||
{
|
||||
const void *lpVtbl;
|
||||
LONG ref;
|
||||
GUID guid;
|
||||
|
||||
IDirectInputImpl* dinput;
|
||||
|
||||
HANDLE hEvent;
|
||||
/* SysKeyboardAImpl */
|
||||
int acquired;
|
||||
int buffersize; /* set in 'SetProperty' */
|
||||
LPDIDEVICEOBJECTDATA buffer; /* buffer for 'GetDeviceData'.
|
||||
Alloc at 'Acquire', Free at
|
||||
'Unacquire' */
|
||||
int count; /* number of objects in use in
|
||||
'buffer' */
|
||||
int start; /* 'buffer' rotates. This is the
|
||||
first in use (if count > 0) */
|
||||
BOOL overflow; /* return DI_BUFFEROVERFLOW in
|
||||
'GetDeviceData' */
|
||||
CRITICAL_SECTION crit;
|
||||
struct IDirectInputDevice2AImpl base;
|
||||
BYTE DInputKeyState[WINE_DINPUT_KEYBOARD_MAX_KEYS];
|
||||
};
|
||||
|
||||
static SysKeyboardImpl* current_lock = NULL;
|
||||
/* Today's acquired device
|
||||
* FIXME: currently this can be only one.
|
||||
* Maybe this should be a linked list or st.
|
||||
* I don't know what the rules are for multiple acquired keyboards,
|
||||
* but 'DI_LOSTFOCUS' and 'DI_UNACQUIRED' exist for a reason.
|
||||
*/
|
||||
|
||||
static BYTE DInputKeyState[WINE_DINPUT_KEYBOARD_MAX_KEYS]; /* array for 'GetDeviceState' */
|
||||
|
||||
static CRITICAL_SECTION keyboard_crit;
|
||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
static BYTE map_dik_code(DWORD scanCode, DWORD vkCode)
|
||||
{
|
||||
0, 0, &keyboard_crit,
|
||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": keyboard_crit") }
|
||||
};
|
||||
static CRITICAL_SECTION keyboard_crit = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
static const BYTE asciiCodes[] =
|
||||
{/*32*/ DIK_SPACE,0,0,0,0,0,0,DIK_APOSTROPHE,
|
||||
/*40*/ 0,0,0,0,DIK_COMMA,DIK_MINUS,DIK_PERIOD,DIK_SLASH,
|
||||
/*48*/ DIK_0,DIK_1,DIK_2,DIK_3,DIK_4,DIK_5,DIK_6,DIK_7,
|
||||
/*56*/ DIK_8,DIK_9,DIK_COLON,DIK_SEMICOLON,0,DIK_EQUALS,0,0,
|
||||
/*64*/ DIK_AT,DIK_A,DIK_B,DIK_C,DIK_D,DIK_E,DIK_F,DIK_G,
|
||||
/*72*/ DIK_H,DIK_I,DIK_J,DIK_K,DIK_L,DIK_M,DIK_N,DIK_O,
|
||||
/*80*/ DIK_P,DIK_Q,DIK_R,DIK_S,DIK_T,DIK_U,DIK_V,DIK_W,
|
||||
/*88*/ DIK_X,DIK_Y,DIK_Z,DIK_LBRACKET,0,DIK_RBRACKET,DIK_CIRCUMFLEX,DIK_UNDERLINE} /*95*/ ;
|
||||
|
||||
static LONG keyboard_users = 0;
|
||||
static HHOOK keyboard_hook = NULL;
|
||||
BYTE out_code = 0;
|
||||
WCHAR c = MapVirtualKeyW(vkCode,MAPVK_VK_TO_CHAR);
|
||||
|
||||
LRESULT CALLBACK KeyboardCallback( int code, WPARAM wparam, LPARAM lparam )
|
||||
{
|
||||
BYTE dik_code;
|
||||
BOOL down;
|
||||
DWORD timestamp;
|
||||
KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
|
||||
BYTE new_diks;
|
||||
if (c > 31 && c < 96)
|
||||
out_code = asciiCodes[c - 32];
|
||||
|
||||
TRACE("(%d,%d,%ld)\n", code, wparam, lparam);
|
||||
if (out_code == 0)
|
||||
out_code = scanCode;
|
||||
|
||||
/** returns now if not HC_ACTION */
|
||||
if (code != HC_ACTION) return CallNextHookEx(keyboard_hook, code, wparam, lparam);
|
||||
|
||||
{
|
||||
dik_code = hook->scanCode;
|
||||
if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
|
||||
down = !(hook->flags & LLKHF_UP);
|
||||
timestamp = hook->time;
|
||||
}
|
||||
|
||||
/** returns now if key event already known */
|
||||
new_diks = (down ? 0x80 : 0);
|
||||
/*if (new_diks != DInputKeyState[dik_code]) return CallNextHookEx(keyboard_hook, code, wparam, lparam); TO BE FIXED */
|
||||
|
||||
DInputKeyState[dik_code] = new_diks;
|
||||
TRACE(" setting %02X to %02X\n", dik_code, DInputKeyState[dik_code]);
|
||||
|
||||
if (current_lock != NULL) {
|
||||
if (current_lock->hEvent) SetEvent(current_lock->hEvent);
|
||||
|
||||
if (current_lock->buffer != NULL) {
|
||||
int n;
|
||||
|
||||
EnterCriticalSection(&(current_lock->crit));
|
||||
|
||||
n = (current_lock->start + current_lock->count) % current_lock->buffersize;
|
||||
|
||||
current_lock->buffer[n].dwOfs = dik_code;
|
||||
current_lock->buffer[n].dwData = down ? 0x80 : 0;
|
||||
current_lock->buffer[n].dwTimeStamp = timestamp;
|
||||
current_lock->buffer[n].dwSequence = current_lock->dinput->evsequence++;
|
||||
|
||||
TRACE("Adding event at offset %d : %ld - %ld - %ld - %ld\n", n,
|
||||
current_lock->buffer[n].dwOfs, current_lock->buffer[n].dwData, current_lock->buffer[n].dwTimeStamp, current_lock->buffer[n].dwSequence);
|
||||
|
||||
if (current_lock->count == current_lock->buffersize) {
|
||||
current_lock->start = ++current_lock->start % current_lock->buffersize;
|
||||
current_lock->overflow = TRUE;
|
||||
} else
|
||||
current_lock->count++;
|
||||
|
||||
LeaveCriticalSection(&(current_lock->crit));
|
||||
}
|
||||
}
|
||||
return CallNextHookEx(keyboard_hook, code, wparam, lparam);
|
||||
return out_code;
|
||||
}
|
||||
|
||||
static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
|
||||
0x0ab8648a,
|
||||
0x7735,
|
||||
0x11d2,
|
||||
{0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
|
||||
static void KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
int dik_code;
|
||||
KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
|
||||
BYTE new_diks;
|
||||
|
||||
if (wparam != WM_KEYDOWN && wparam != WM_KEYUP &&
|
||||
wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP)
|
||||
return;
|
||||
|
||||
TRACE("(%p) %ld,%ld\n", iface, wparam, lparam);
|
||||
|
||||
dik_code = map_dik_code(hook->scanCode & 0xff,hook->vkCode);
|
||||
/* R-Shift is special - it is an extended key with separate scan code */
|
||||
if (hook->flags & LLKHF_EXTENDED && dik_code != 0x36)
|
||||
dik_code |= 0x80;
|
||||
|
||||
new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;
|
||||
|
||||
/* returns now if key event already known */
|
||||
if (new_diks == This->DInputKeyState[dik_code])
|
||||
return;
|
||||
|
||||
This->DInputKeyState[dik_code] = new_diks;
|
||||
TRACE(" setting %02X to %02X\n", dik_code, This->DInputKeyState[dik_code]);
|
||||
|
||||
dik_code = id_to_offset(&This->base.data_format, DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON);
|
||||
EnterCriticalSection(&This->base.crit);
|
||||
queue_event((LPDIRECTINPUTDEVICE8A)This, dik_code, new_diks, hook->time, This->base.dinput->evsequence++);
|
||||
LeaveCriticalSection(&This->base.crit);
|
||||
}
|
||||
|
||||
const GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
|
||||
0x0ab8648a, 0x7735, 0x11d2, {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
|
||||
};
|
||||
|
||||
static void fill_keyboard_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version) {
|
||||
DWORD dwSize;
|
||||
DIDEVICEINSTANCEA ddi;
|
||||
|
||||
|
||||
dwSize = lpddi->dwSize;
|
||||
|
||||
TRACE("%ld %p\n", dwSize, lpddi);
|
||||
|
||||
TRACE("%d %p\n", dwSize, lpddi);
|
||||
|
||||
memset(lpddi, 0, dwSize);
|
||||
memset(&ddi, 0, sizeof(ddi));
|
||||
|
||||
|
@ -181,14 +138,14 @@ static void fill_keyboard_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD ver
|
|||
static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version) {
|
||||
DWORD dwSize;
|
||||
DIDEVICEINSTANCEW ddi;
|
||||
|
||||
|
||||
dwSize = lpddi->dwSize;
|
||||
|
||||
TRACE("%ld %p\n", dwSize, lpddi);
|
||||
|
||||
TRACE("%d %p\n", dwSize, lpddi);
|
||||
|
||||
memset(lpddi, 0, dwSize);
|
||||
memset(&ddi, 0, sizeof(ddi));
|
||||
|
||||
|
||||
ddi.dwSize = dwSize;
|
||||
ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
|
||||
ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
|
||||
|
@ -201,7 +158,7 @@ static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
|
|||
|
||||
memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
|
||||
}
|
||||
|
||||
|
||||
static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
|
||||
{
|
||||
if (id != 0)
|
||||
|
@ -211,9 +168,9 @@ static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEI
|
|||
((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 0x0800)) ||
|
||||
(((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 0x0800))) {
|
||||
TRACE("Enumerating the Keyboard device\n");
|
||||
|
||||
|
||||
fill_keyboard_dideviceinstanceA(lpddi, version);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -231,7 +188,7 @@ static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEI
|
|||
TRACE("Enumerating the Keyboard device\n");
|
||||
|
||||
fill_keyboard_dideviceinstanceW(lpddi, version);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -241,23 +198,44 @@ static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEI
|
|||
static SysKeyboardImpl *alloc_device(REFGUID rguid, const void *kvt, IDirectInputImpl *dinput)
|
||||
{
|
||||
SysKeyboardImpl* newDevice;
|
||||
DWORD kbd_users;
|
||||
LPDIDATAFORMAT df = NULL;
|
||||
int i, idx = 0;
|
||||
|
||||
newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardImpl));
|
||||
newDevice->lpVtbl = kvt;
|
||||
newDevice->ref = 1;
|
||||
memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
|
||||
newDevice->dinput = dinput;
|
||||
InitializeCriticalSection(&(newDevice->crit));
|
||||
newDevice->base.lpVtbl = kvt;
|
||||
newDevice->base.ref = 1;
|
||||
memcpy(&newDevice->base.guid, rguid, sizeof(*rguid));
|
||||
newDevice->base.dinput = dinput;
|
||||
newDevice->base.event_proc = KeyboardCallback;
|
||||
InitializeCriticalSection(&newDevice->base.crit);
|
||||
newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit");
|
||||
|
||||
EnterCriticalSection(&keyboard_crit);
|
||||
kbd_users = InterlockedIncrement(&keyboard_users);
|
||||
if (1 == kbd_users) {
|
||||
keyboard_hook = SetWindowsHookExW( WH_KEYBOARD_LL, KeyboardCallback, DINPUT_instance, 0 );
|
||||
/* Create copy of default data format */
|
||||
if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIKeyboard.dwSize))) goto failed;
|
||||
memcpy(df, &c_dfDIKeyboard, c_dfDIKeyboard.dwSize);
|
||||
if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed;
|
||||
|
||||
for (i = 0; i < df->dwNumObjs; i++)
|
||||
{
|
||||
char buf[MAX_PATH];
|
||||
|
||||
if (!GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), buf, sizeof(buf)))
|
||||
continue;
|
||||
|
||||
memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[i], df->dwObjSize);
|
||||
df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
|
||||
}
|
||||
LeaveCriticalSection(&keyboard_crit);
|
||||
df->dwNumObjs = idx;
|
||||
|
||||
newDevice->base.data_format.wine_df = df;
|
||||
IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->base.dinput);
|
||||
return newDevice;
|
||||
|
||||
failed:
|
||||
if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
|
||||
HeapFree(GetProcessHeap(), 0, df);
|
||||
HeapFree(GetProcessHeap(), 0, newDevice);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -272,6 +250,7 @@ static HRESULT keyboarddev_create_deviceA(IDirectInputImpl *dinput, REFGUID rgui
|
|||
IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
|
||||
*pdev = (IDirectInputDeviceA*) alloc_device(rguid, &SysKeyboardAvt, dinput);
|
||||
TRACE("Creating a Keyboard device (%p)\n", *pdev);
|
||||
if (!*pdev) return DIERR_OUTOFMEMORY;
|
||||
return DI_OK;
|
||||
} else
|
||||
return DIERR_NOINTERFACE;
|
||||
|
@ -290,6 +269,7 @@ static HRESULT keyboarddev_create_deviceW(IDirectInputImpl *dinput, REFGUID rgui
|
|||
IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
|
||||
*pdev = (IDirectInputDeviceW*) alloc_device(rguid, &SysKeyboardWvt, dinput);
|
||||
TRACE("Creating a Keyboard device (%p)\n", *pdev);
|
||||
if (!*pdev) return DIERR_OUTOFMEMORY;
|
||||
return DI_OK;
|
||||
} else
|
||||
return DIERR_NOINTERFACE;
|
||||
|
@ -305,306 +285,36 @@ const struct dinput_device keyboard_device = {
|
|||
keyboarddev_create_deviceW
|
||||
};
|
||||
|
||||
static ULONG WINAPI SysKeyboardAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
ULONG ref;
|
||||
DWORD kbd_users;
|
||||
|
||||
ref = InterlockedDecrement(&(This->ref));
|
||||
if (ref)
|
||||
return ref;
|
||||
|
||||
EnterCriticalSection(&keyboard_crit);
|
||||
kbd_users = InterlockedDecrement(&keyboard_users);
|
||||
if (0 == kbd_users) {
|
||||
UnhookWindowsHookEx( keyboard_hook );
|
||||
keyboard_hook = 0;
|
||||
}
|
||||
LeaveCriticalSection(&keyboard_crit);
|
||||
|
||||
/* Free the data queue */
|
||||
HeapFree(GetProcessHeap(),0,This->buffer);
|
||||
|
||||
DeleteCriticalSection(&(This->crit));
|
||||
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
|
||||
LPDIRECTINPUTDEVICE8A iface,REFGUID rguid,LPCDIPROPHEADER ph
|
||||
)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
|
||||
TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
|
||||
TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
|
||||
ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
|
||||
if (!HIWORD(rguid)) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
|
||||
|
||||
TRACE("(buffersize=%ld)\n",pd->dwData);
|
||||
|
||||
if (This->acquired)
|
||||
return DIERR_INVALIDPARAM;
|
||||
|
||||
This->buffersize = pd->dwData;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WARN("Unknown type %p\n",rguid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardAImpl_GetProperty(
|
||||
LPDIRECTINPUTDEVICE8A iface,REFGUID rguid,LPDIPROPHEADER ph
|
||||
)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
|
||||
TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
|
||||
TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
|
||||
ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
|
||||
if (!HIWORD(rguid)) {
|
||||
switch (LOWORD(rguid)) {
|
||||
case (DWORD) DIPROP_BUFFERSIZE: {
|
||||
LPDIPROPDWORD pd = (LPDIPROPDWORD)ph;
|
||||
|
||||
TRACE("(buffersize=%ld)\n",pd->dwData);
|
||||
|
||||
if (This->acquired)
|
||||
return DIERR_INVALIDPARAM;
|
||||
|
||||
pd->dwData = This->buffersize;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WARN("Unknown type %p\n",rguid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
|
||||
LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr
|
||||
)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
TRACE("(%p)->(%ld,%p)\n", This, len, ptr);
|
||||
TRACE("(%p)->(%d,%p)\n", This, len, ptr);
|
||||
|
||||
/* Note: device does not need to be acquired */
|
||||
if (len != WINE_DINPUT_KEYBOARD_MAX_KEYS)
|
||||
return DIERR_INVALIDPARAM;
|
||||
if (!This->base.acquired) return DIERR_NOTACQUIRED;
|
||||
|
||||
MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, 0);
|
||||
if (len != This->base.data_format.user_df->dwDataSize )
|
||||
return DIERR_INVALIDPARAM;
|
||||
|
||||
EnterCriticalSection(&(This->crit));
|
||||
EnterCriticalSection(&This->base.crit);
|
||||
|
||||
if (TRACE_ON(dinput)) {
|
||||
int i;
|
||||
for (i = 0; i < WINE_DINPUT_KEYBOARD_MAX_KEYS; i++) {
|
||||
if (DInputKeyState[i] != 0x00) {
|
||||
TRACE(" - %02X: %02x\n", i, DInputKeyState[i]);
|
||||
}
|
||||
if (This->DInputKeyState[i] != 0x00)
|
||||
TRACE(" - %02X: %02x\n", i, This->DInputKeyState[i]);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(ptr, DInputKeyState, WINE_DINPUT_KEYBOARD_MAX_KEYS);
|
||||
LeaveCriticalSection(&(This->crit));
|
||||
fill_DataFormat(ptr, len, This->DInputKeyState, &This->base.data_format);
|
||||
LeaveCriticalSection(&This->base.crit);
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
|
||||
LPDIRECTINPUTDEVICE8A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
|
||||
LPDWORD entries,DWORD flags
|
||||
)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
int ret = DI_OK, i = 0;
|
||||
|
||||
TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
|
||||
This,dodsize,dod,entries,entries?*entries:0,flags);
|
||||
|
||||
if (This->acquired == 0)
|
||||
return DIERR_NOTACQUIRED;
|
||||
|
||||
if (This->buffer == NULL)
|
||||
return DIERR_NOTBUFFERED;
|
||||
|
||||
if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3))
|
||||
return DIERR_INVALIDPARAM;
|
||||
|
||||
MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, 0);
|
||||
|
||||
EnterCriticalSection(&(This->crit));
|
||||
|
||||
/* Copy item at a time for the case dodsize > sizeof(buffer[n]) */
|
||||
while ((i < *entries || *entries == INFINITE) && i < This->count)
|
||||
{
|
||||
if (dod != NULL)
|
||||
{
|
||||
int n = (This->start + i) % This->buffersize;
|
||||
LPDIDEVICEOBJECTDATA pd
|
||||
= (LPDIDEVICEOBJECTDATA)((BYTE *)dod + dodsize * i);
|
||||
pd->dwOfs = This->buffer[n].dwOfs;
|
||||
pd->dwData = This->buffer[n].dwData;
|
||||
pd->dwTimeStamp = This->buffer[n].dwTimeStamp;
|
||||
pd->dwSequence = This->buffer[n].dwSequence;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
*entries = i;
|
||||
|
||||
if (This->overflow)
|
||||
ret = DI_BUFFEROVERFLOW;
|
||||
|
||||
if (!(flags & DIGDD_PEEK))
|
||||
{
|
||||
/* Empty buffer */
|
||||
This->count -= i;
|
||||
This->start = (This->start + i) % This->buffersize;
|
||||
This->overflow = FALSE;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&(This->crit));
|
||||
|
||||
TRACE("Returning %ld events queued\n", *entries);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardAImpl_EnumObjects(
|
||||
LPDIRECTINPUTDEVICE8A iface,
|
||||
LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
|
||||
LPVOID lpvRef,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
DIDEVICEOBJECTINSTANCEA ddoi;
|
||||
int i;
|
||||
|
||||
TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags);
|
||||
if (TRACE_ON(dinput)) {
|
||||
TRACE(" - flags = ");
|
||||
_dump_EnumObjects_flags(dwFlags);
|
||||
TRACE("\n");
|
||||
}
|
||||
|
||||
/* Only the fields till dwFFMaxForce are relevant */
|
||||
memset(&ddoi, 0, sizeof(ddoi));
|
||||
ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce);
|
||||
|
||||
for (i = 0; i < WINE_DINPUT_KEYBOARD_MAX_KEYS; i++) {
|
||||
/* Report 255 keys :-) */
|
||||
ddoi.guidType = GUID_Key;
|
||||
ddoi.dwOfs = i;
|
||||
ddoi.dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_BUTTON;
|
||||
GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), ddoi.tszName, sizeof(ddoi.tszName));
|
||||
_dump_OBJECTINSTANCEA(&ddoi);
|
||||
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
|
||||
}
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardWImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface,
|
||||
LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
|
||||
LPVOID lpvRef,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
|
||||
device_enumobjects_AtoWcb_data data;
|
||||
|
||||
data.lpCallBack = lpCallback;
|
||||
data.lpvRef = lpvRef;
|
||||
|
||||
return SysKeyboardAImpl_EnumObjects((LPDIRECTINPUTDEVICE8A) This, (LPDIENUMDEVICEOBJECTSCALLBACKA) DIEnumDevicesCallbackAtoW, (LPVOID) &data, dwFlags);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface);
|
||||
|
||||
static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
|
||||
TRACE("(this=%p)\n",This);
|
||||
|
||||
if (This->acquired)
|
||||
return S_FALSE;
|
||||
|
||||
This->acquired = 1;
|
||||
|
||||
if (current_lock != NULL) {
|
||||
FIXME("Not more than one keyboard can be acquired at the same time.\n");
|
||||
SysKeyboardAImpl_Unacquire(iface);
|
||||
}
|
||||
|
||||
current_lock = This;
|
||||
|
||||
if (This->buffersize > 0) {
|
||||
This->buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
This->buffersize * sizeof(*(This->buffer)));
|
||||
This->start = 0;
|
||||
This->count = 0;
|
||||
This->overflow = FALSE;
|
||||
} else {
|
||||
This->buffer = NULL;
|
||||
}
|
||||
|
||||
/*keyboard_hook = SetWindowsHookExW( WH_KEYBOARD_LL, KeyboardCallback, DINPUT_instance, 0 );*/
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
TRACE("(this=%p)\n",This);
|
||||
|
||||
if (This->acquired == 0)
|
||||
return DI_NOEFFECT;
|
||||
|
||||
/* No more locks */
|
||||
if (current_lock == This)
|
||||
current_lock = NULL;
|
||||
else
|
||||
ERR("this != current_lock\n");
|
||||
|
||||
/* Unacquire device */
|
||||
This->acquired = 0;
|
||||
|
||||
if (This->buffersize >= 0) {
|
||||
HeapFree(GetProcessHeap(), 0, This->buffer);
|
||||
This->buffer = NULL;
|
||||
}
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardAImpl_SetEventNotification(LPDIRECTINPUTDEVICE8A iface,
|
||||
HANDLE hnd) {
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
|
||||
TRACE("(this=%p,%p)\n",This,hnd);
|
||||
|
||||
This->hEvent = hnd;
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetCapabilities : get the device capablitites
|
||||
* GetCapabilities : get the device capabilities
|
||||
*/
|
||||
static HRESULT WINAPI SysKeyboardAImpl_GetCapabilities(
|
||||
LPDIRECTINPUTDEVICE8A iface,
|
||||
|
@ -619,15 +329,15 @@ static HRESULT WINAPI SysKeyboardAImpl_GetCapabilities(
|
|||
WARN("invalid parameter\n");
|
||||
return DIERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
|
||||
devcaps.dwSize = lpDIDevCaps->dwSize;
|
||||
devcaps.dwFlags = DIDC_ATTACHED;
|
||||
if (This->dinput->dwVersion >= 0x0800)
|
||||
if (This->base.dinput->dwVersion >= 0x0800)
|
||||
devcaps.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8);
|
||||
else
|
||||
devcaps.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
|
||||
devcaps.dwAxes = 0;
|
||||
devcaps.dwButtons = WINE_DINPUT_KEYBOARD_MAX_KEYS;
|
||||
devcaps.dwButtons = This->base.data_format.wine_df->dwNumObjs;
|
||||
devcaps.dwPOVs = 0;
|
||||
devcaps.dwFFSamplePeriod = 0;
|
||||
devcaps.dwFFMinTimeResolution = 0;
|
||||
|
@ -636,7 +346,7 @@ static HRESULT WINAPI SysKeyboardAImpl_GetCapabilities(
|
|||
devcaps.dwFFDriverVersion = 0;
|
||||
|
||||
memcpy(lpDIDevCaps, &devcaps, lpDIDevCaps->dwSize);
|
||||
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
|
@ -651,32 +361,18 @@ SysKeyboardAImpl_GetObjectInfo(
|
|||
DWORD dwObj,
|
||||
DWORD dwHow)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
DIDEVICEOBJECTINSTANCEA ddoi;
|
||||
DWORD dwSize = pdidoi->dwSize;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(this=%p,%p,%ld,0x%08lx)\n", This, pdidoi, dwObj, dwHow);
|
||||
res = IDirectInputDevice2AImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
|
||||
if (res != DI_OK) return res;
|
||||
|
||||
if (dwHow == DIPH_BYID) {
|
||||
WARN(" querying by id not supported yet...\n");
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
memset(pdidoi, 0, dwSize);
|
||||
memset(&ddoi, 0, sizeof(ddoi));
|
||||
|
||||
ddoi.dwSize = dwSize;
|
||||
ddoi.guidType = GUID_Key;
|
||||
ddoi.dwOfs = dwObj;
|
||||
ddoi.dwType = DIDFT_MAKEINSTANCE(dwObj) | DIDFT_BUTTON;
|
||||
GetKeyNameTextA(((dwObj & 0x7f) << 16) | ((dwObj & 0x80) << 17), ddoi.tszName, sizeof(ddoi.tszName));
|
||||
|
||||
/* And return our just filled device object instance structure */
|
||||
memcpy(pdidoi, &ddoi, (dwSize < sizeof(ddoi) ? dwSize : sizeof(ddoi)));
|
||||
if (!GetKeyNameTextA((DIDFT_GETINSTANCE(pdidoi->dwType) & 0x80) << 17 |
|
||||
(DIDFT_GETINSTANCE(pdidoi->dwType) & 0x7f) << 16,
|
||||
pdidoi->tszName, sizeof(pdidoi->tszName)))
|
||||
return DIERR_OBJECTNOTFOUND;
|
||||
|
||||
_dump_OBJECTINSTANCEA(pdidoi);
|
||||
|
||||
return DI_OK;
|
||||
return res;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
|
||||
|
@ -684,32 +380,19 @@ static HRESULT WINAPI SysKeyboardWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface
|
|||
DWORD dwObj,
|
||||
DWORD dwHow)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
DIDEVICEOBJECTINSTANCEW ddoi;
|
||||
DWORD dwSize = pdidoi->dwSize;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(this=%p,%p,%ld,0x%08lx)\n", This, pdidoi, dwObj, dwHow);
|
||||
res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
|
||||
if (res != DI_OK) return res;
|
||||
|
||||
if (dwHow == DIPH_BYID) {
|
||||
WARN(" querying by id not supported yet...\n");
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
memset(pdidoi, 0, dwSize);
|
||||
memset(&ddoi, 0, sizeof(ddoi));
|
||||
|
||||
ddoi.dwSize = dwSize;
|
||||
ddoi.guidType = GUID_Key;
|
||||
ddoi.dwOfs = dwObj;
|
||||
ddoi.dwType = DIDFT_MAKEINSTANCE(dwObj) | DIDFT_BUTTON;
|
||||
GetKeyNameTextW(((dwObj & 0x7f) << 16) | ((dwObj & 0x80) << 17), ddoi.tszName, sizeof(ddoi.tszName));
|
||||
|
||||
/* And return our just filled device object instance structure */
|
||||
memcpy(pdidoi, &ddoi, (dwSize < sizeof(ddoi) ? dwSize : sizeof(ddoi)));
|
||||
if (!GetKeyNameTextW((DIDFT_GETINSTANCE(pdidoi->dwType) & 0x80) << 17 |
|
||||
(DIDFT_GETINSTANCE(pdidoi->dwType) & 0x7f) << 16,
|
||||
pdidoi->tszName,
|
||||
sizeof(pdidoi->tszName)/sizeof(pdidoi->tszName[0])))
|
||||
return DIERR_OBJECTNOTFOUND;
|
||||
|
||||
_dump_OBJECTINSTANCEW(pdidoi);
|
||||
|
||||
return DI_OK;
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -727,12 +410,12 @@ static HRESULT WINAPI SysKeyboardAImpl_GetDeviceInfo(
|
|||
return DI_OK;
|
||||
}
|
||||
|
||||
fill_keyboard_dideviceinstanceA(pdidi, This->dinput->dwVersion);
|
||||
|
||||
fill_keyboard_dideviceinstanceA(pdidi, This->base.dinput->dwVersion);
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SysKeyboardWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW pdidi)
|
||||
static HRESULT WINAPI SysKeyboardWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW pdidi)
|
||||
{
|
||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||
TRACE("(this=%p,%p)\n", This, pdidi);
|
||||
|
@ -742,8 +425,44 @@ static HRESULT WINAPI SysKeyboardWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface
|
|||
return DI_OK;
|
||||
}
|
||||
|
||||
fill_keyboard_dideviceinstanceW(pdidi, This->dinput->dwVersion);
|
||||
fill_keyboard_dideviceinstanceW(pdidi, This->base.dinput->dwVersion);
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetProperty : Retrieves information about the input device.
|
||||
*/
|
||||
static HRESULT WINAPI SysKeyboardAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
|
||||
REFGUID rguid, LPDIPROPHEADER pdiph)
|
||||
{
|
||||
TRACE("(%p) %s,%p\n", iface, debugstr_guid(rguid), pdiph);
|
||||
_dump_DIPROPHEADER(pdiph);
|
||||
|
||||
if (HIWORD(rguid)) return DI_OK;
|
||||
|
||||
switch (LOWORD(rguid))
|
||||
{
|
||||
case (DWORD_PTR)DIPROP_KEYNAME:
|
||||
{
|
||||
HRESULT hr;
|
||||
LPDIPROPSTRING ps = (LPDIPROPSTRING)pdiph;
|
||||
DIDEVICEOBJECTINSTANCEW didoi;
|
||||
|
||||
if (pdiph->dwSize != sizeof(DIPROPSTRING))
|
||||
return DIERR_INVALIDPARAM;
|
||||
|
||||
didoi.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW);
|
||||
|
||||
hr = SysKeyboardWImpl_GetObjectInfo((LPDIRECTINPUTDEVICE8W)iface , &didoi,
|
||||
ps->diph.dwObj, ps->diph.dwHow);
|
||||
if (hr == DI_OK)
|
||||
memcpy(ps->wsz, didoi.tszName, sizeof(ps->wsz));
|
||||
return hr;
|
||||
}
|
||||
default:
|
||||
return IDirectInputDevice2AImpl_GetProperty( iface, rguid, pdiph );
|
||||
}
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
|
@ -751,17 +470,17 @@ static const IDirectInputDevice8AVtbl SysKeyboardAvt =
|
|||
{
|
||||
IDirectInputDevice2AImpl_QueryInterface,
|
||||
IDirectInputDevice2AImpl_AddRef,
|
||||
SysKeyboardAImpl_Release,
|
||||
IDirectInputDevice2AImpl_Release,
|
||||
SysKeyboardAImpl_GetCapabilities,
|
||||
SysKeyboardAImpl_EnumObjects,
|
||||
SysKeyboardAImpl_GetProperty,
|
||||
SysKeyboardAImpl_SetProperty,
|
||||
SysKeyboardAImpl_Acquire,
|
||||
SysKeyboardAImpl_Unacquire,
|
||||
IDirectInputDevice2AImpl_EnumObjects,
|
||||
SysKeyboardAImpl_GetProperty,
|
||||
IDirectInputDevice2AImpl_SetProperty,
|
||||
IDirectInputDevice2AImpl_Acquire,
|
||||
IDirectInputDevice2AImpl_Unacquire,
|
||||
SysKeyboardAImpl_GetDeviceState,
|
||||
SysKeyboardAImpl_GetDeviceData,
|
||||
IDirectInputDevice2AImpl_GetDeviceData,
|
||||
IDirectInputDevice2AImpl_SetDataFormat,
|
||||
SysKeyboardAImpl_SetEventNotification,
|
||||
IDirectInputDevice2AImpl_SetEventNotification,
|
||||
IDirectInputDevice2AImpl_SetCooperativeLevel,
|
||||
SysKeyboardAImpl_GetObjectInfo,
|
||||
SysKeyboardAImpl_GetDeviceInfo,
|
||||
|
@ -774,7 +493,7 @@ static const IDirectInputDevice8AVtbl SysKeyboardAvt =
|
|||
IDirectInputDevice2AImpl_SendForceFeedbackCommand,
|
||||
IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
|
||||
IDirectInputDevice2AImpl_Escape,
|
||||
IDirectInputDevice2AImpl_Poll,
|
||||
IDirectInputDevice2AImpl_Poll,
|
||||
IDirectInputDevice2AImpl_SendDeviceData,
|
||||
IDirectInputDevice7AImpl_EnumEffectsInFile,
|
||||
IDirectInputDevice7AImpl_WriteEffectToFile,
|
||||
|
@ -793,17 +512,17 @@ static const IDirectInputDevice8WVtbl SysKeyboardWvt =
|
|||
{
|
||||
IDirectInputDevice2WImpl_QueryInterface,
|
||||
XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
|
||||
XCAST(Release)SysKeyboardAImpl_Release,
|
||||
XCAST(Release)IDirectInputDevice2AImpl_Release,
|
||||
XCAST(GetCapabilities)SysKeyboardAImpl_GetCapabilities,
|
||||
SysKeyboardWImpl_EnumObjects,
|
||||
XCAST(GetProperty)SysKeyboardAImpl_GetProperty,
|
||||
XCAST(SetProperty)SysKeyboardAImpl_SetProperty,
|
||||
XCAST(Acquire)SysKeyboardAImpl_Acquire,
|
||||
XCAST(Unacquire)SysKeyboardAImpl_Unacquire,
|
||||
IDirectInputDevice2WImpl_EnumObjects,
|
||||
XCAST(GetProperty)SysKeyboardAImpl_GetProperty,
|
||||
XCAST(SetProperty)IDirectInputDevice2AImpl_SetProperty,
|
||||
XCAST(Acquire)IDirectInputDevice2AImpl_Acquire,
|
||||
XCAST(Unacquire)IDirectInputDevice2AImpl_Unacquire,
|
||||
XCAST(GetDeviceState)SysKeyboardAImpl_GetDeviceState,
|
||||
XCAST(GetDeviceData)SysKeyboardAImpl_GetDeviceData,
|
||||
XCAST(GetDeviceData)IDirectInputDevice2AImpl_GetDeviceData,
|
||||
XCAST(SetDataFormat)IDirectInputDevice2AImpl_SetDataFormat,
|
||||
XCAST(SetEventNotification)SysKeyboardAImpl_SetEventNotification,
|
||||
XCAST(SetEventNotification)IDirectInputDevice2AImpl_SetEventNotification,
|
||||
XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
|
||||
SysKeyboardWImpl_GetObjectInfo,
|
||||
SysKeyboardWImpl_GetDeviceInfo,
|
||||
|
@ -816,7 +535,7 @@ static const IDirectInputDevice8WVtbl SysKeyboardWvt =
|
|||
XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
|
||||
XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
|
||||
XCAST(Escape)IDirectInputDevice2AImpl_Escape,
|
||||
XCAST(Poll)IDirectInputDevice2AImpl_Poll,
|
||||
XCAST(Poll)IDirectInputDevice2AImpl_Poll,
|
||||
XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
|
||||
IDirectInputDevice7WImpl_EnumEffectsInFile,
|
||||
IDirectInputDevice7WImpl_WriteEffectToFile,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -31,6 +31,7 @@
|
|||
#include "dinput.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
|
||||
|
||||
|
@ -115,9 +116,6 @@ static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
|
|||
static LONG register_progid(WCHAR const *clsid,
|
||||
char const *progid, char const *curver_progid,
|
||||
char const *name, char const *extra);
|
||||
static LONG recursive_delete_key(HKEY key);
|
||||
static LONG recursive_delete_keyA(HKEY base, char const *name);
|
||||
static LONG recursive_delete_keyW(HKEY base, WCHAR const *name);
|
||||
|
||||
/***********************************************************************
|
||||
* register_interfaces
|
||||
|
@ -148,7 +146,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
|
|||
}
|
||||
|
||||
if (list->base_iid) {
|
||||
register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
|
||||
res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
|
@ -160,7 +158,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
|
|||
KEY_READ | KEY_WRITE, NULL, &key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
|
||||
wsprintfW(buf, fmt, list->num_methods);
|
||||
sprintfW(buf, fmt, list->num_methods);
|
||||
res = RegSetValueExW(key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)buf,
|
||||
(lstrlenW(buf) + 1) * sizeof(WCHAR));
|
||||
|
@ -170,12 +168,12 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
|
|||
}
|
||||
|
||||
if (list->ps_clsid) {
|
||||
register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
|
||||
res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (list->ps_clsid32) {
|
||||
register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
|
||||
res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
|
@ -206,7 +204,8 @@ static HRESULT unregister_interfaces(struct regsvr_interface const *list)
|
|||
WCHAR buf[39];
|
||||
|
||||
StringFromGUID2(list->iid, buf, 39);
|
||||
res = recursive_delete_keyW(interface_key, buf);
|
||||
//res = RegDeleteTreeW(interface_key, buf);
|
||||
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
RegCloseKey(interface_key);
|
||||
|
@ -313,16 +312,19 @@ static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
|
|||
WCHAR buf[39];
|
||||
|
||||
StringFromGUID2(list->clsid, buf, 39);
|
||||
res = recursive_delete_keyW(coclass_key, buf);
|
||||
//res = RegDeleteTreeW(coclass_key, buf);
|
||||
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
|
||||
if (list->progid) {
|
||||
res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
|
||||
// res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
|
||||
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
}
|
||||
|
||||
if (list->viprogid) {
|
||||
res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid);
|
||||
//res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
|
||||
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
}
|
||||
}
|
||||
|
@ -434,70 +436,6 @@ error_close_progid_key:
|
|||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* recursive_delete_key
|
||||
*/
|
||||
static LONG recursive_delete_key(HKEY key)
|
||||
{
|
||||
LONG res;
|
||||
WCHAR subkey_name[MAX_PATH];
|
||||
DWORD cName;
|
||||
HKEY subkey;
|
||||
|
||||
for (;;) {
|
||||
cName = sizeof(subkey_name) / sizeof(WCHAR);
|
||||
res = RegEnumKeyExW(key, 0, subkey_name, &cName,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
|
||||
res = ERROR_SUCCESS; /* presumably we're done enumerating */
|
||||
break;
|
||||
}
|
||||
res = RegOpenKeyExW(key, subkey_name, 0,
|
||||
KEY_READ | KEY_WRITE, &subkey);
|
||||
if (res == ERROR_FILE_NOT_FOUND) continue;
|
||||
if (res != ERROR_SUCCESS) break;
|
||||
|
||||
res = recursive_delete_key(subkey);
|
||||
RegCloseKey(subkey);
|
||||
if (res != ERROR_SUCCESS) break;
|
||||
}
|
||||
|
||||
if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* recursive_delete_keyA
|
||||
*/
|
||||
static LONG recursive_delete_keyA(HKEY base, char const *name)
|
||||
{
|
||||
LONG res;
|
||||
HKEY key;
|
||||
|
||||
res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
|
||||
if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
|
||||
if (res != ERROR_SUCCESS) return res;
|
||||
res = recursive_delete_key(key);
|
||||
RegCloseKey(key);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* recursive_delete_keyW
|
||||
*/
|
||||
static LONG recursive_delete_keyW(HKEY base, WCHAR const *name)
|
||||
{
|
||||
LONG res;
|
||||
HKEY key;
|
||||
|
||||
res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key);
|
||||
if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
|
||||
if (res != ERROR_SUCCESS) return res;
|
||||
res = recursive_delete_key(key);
|
||||
RegCloseKey(key);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* coclass list
|
||||
*/
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define WINE_FILEDESCRIPTION_STR "Wine DirectInput"
|
||||
|
|
|
@ -440,6 +440,14 @@ DECL_WINELIB_TYPE_AW(DIDEVICEINSTANCE)
|
|||
DECL_WINELIB_TYPE_AW(LPDIDEVICEINSTANCE)
|
||||
DECL_WINELIB_TYPE_AW(LPCDIDEVICEINSTANCE)
|
||||
|
||||
#define DIEDBSFL_ATTACHEDONLY 0x00000000
|
||||
#define DIEDBSFL_THISUSER 0x00000010
|
||||
#define DIEDBSFL_FORCEFEEDBACK DIEDFL_FORCEFEEDBACK
|
||||
#define DIEDBSFL_AVAILABLEDEVICES 0x00001000
|
||||
#define DIEDBSFL_MULTIMICEKEYBOARDS 0x00002000
|
||||
#define DIEDBSFL_NONGAMINGDEVICES 0x00004000
|
||||
#define DIEDBSFL_VALID 0x00007110
|
||||
|
||||
typedef BOOL (CALLBACK *LPDIENUMDEVICESCALLBACKA)(LPCDIDEVICEINSTANCEA,LPVOID);
|
||||
typedef BOOL (CALLBACK *LPDIENUMDEVICESCALLBACKW)(LPCDIDEVICEINSTANCEW,LPVOID);
|
||||
DECL_WINELIB_TYPE_AW(LPDIENUMDEVICESCALLBACK)
|
||||
|
@ -827,6 +835,10 @@ typedef struct DIDEVCAPS {
|
|||
#define DISCL_NONEXCLUSIVE 0x00000002
|
||||
#define DISCL_FOREGROUND 0x00000004
|
||||
#define DISCL_BACKGROUND 0x00000008
|
||||
#define DISCL_NOWINKEY 0x00000010
|
||||
|
||||
/* Device FF flags */
|
||||
#define DISFFC_RESET 0x00000001
|
||||
|
||||
#define DIEFT_ALL 0x00000000
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628
|
|||
reactos/dll/win32/wldap32 # Autosync
|
||||
reactos/dll/win32/wmi # Autosync
|
||||
reactos/dll/win32/wtsapi32 # Autosync
|
||||
reactos/dll/directx/dinput # Synced to Wine-0_9_5
|
||||
reactos/dll/directx/dinput # Synced to Wine-1_1_4
|
||||
reactos/dll/directx/dinput8 # Synced to Wine-0_9_5
|
||||
reactos/dll/directx/dplay # Synced to Wine-0_9_5
|
||||
reactos/dll/directx/dplayx # Synced to Wine-0_9_5
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue