/*		DirectInput Mouse device
 *
 * Copyright 1998 Marcus Meissner
 * Copyright 1998,1999 Lionel Ulmer
 * Copyright 2000-2001 TransGaming Technologies Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

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

#include <stdarg.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "dinput.h"

#include "dinput_private.h"
#include "device_private.h"
#include "wine/debug.h"
#include "wine/unicode.h"

#define MOUSE_HACK

WINE_DEFAULT_DEBUG_CHANNEL(dinput);

/* Wine mouse driver object instances */
#define WINE_MOUSE_X_AXIS_INSTANCE   0
#define WINE_MOUSE_Y_AXIS_INSTANCE   1
#define WINE_MOUSE_Z_AXIS_INSTANCE   2
#define WINE_MOUSE_L_BUTTON_INSTANCE 0
#define WINE_MOUSE_R_BUTTON_INSTANCE 1
#define WINE_MOUSE_M_BUTTON_INSTANCE 2
#define WINE_MOUSE_D_BUTTON_INSTANCE 3

/* ------------------------------- */
/* Wine mouse internal data format */
/* ------------------------------- */

/* Constants used to access the offset array */
#define WINE_MOUSE_X_POSITION 0
#define WINE_MOUSE_Y_POSITION 1
#define WINE_MOUSE_Z_POSITION 2
#define WINE_MOUSE_L_POSITION 3
#define WINE_MOUSE_R_POSITION 4
#define WINE_MOUSE_M_POSITION 5

typedef struct {
    LONG lX;
    LONG lY;
    LONG lZ;
    BYTE rgbButtons[4];
} Wine_InternalMouseData;

#define WINE_INTERNALMOUSE_NUM_OBJS 6

static const DIOBJECTDATAFORMAT Wine_InternalMouseObjectFormat[WINE_INTERNALMOUSE_NUM_OBJS] = {
    { &GUID_XAxis,   FIELD_OFFSET(Wine_InternalMouseData, lX),
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 },
    { &GUID_YAxis,   FIELD_OFFSET(Wine_InternalMouseData, lY),
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 },
    { &GUID_ZAxis,   FIELD_OFFSET(Wine_InternalMouseData, lZ),
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 },
    { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 0,
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 },
    { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 1,
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 },
    { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 2,
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 }
};

static const DIDATAFORMAT Wine_InternalMouseFormat = {
    0, /* dwSize - unused */
    0, /* dwObjsize - unused */
    0, /* dwFlags - unused */
    sizeof(Wine_InternalMouseData),
    WINE_INTERNALMOUSE_NUM_OBJS, /* dwNumObjs */
    (LPDIOBJECTDATAFORMAT) Wine_InternalMouseObjectFormat
};

static const IDirectInputDevice8AVtbl SysMouseAvt;
static const IDirectInputDevice8WVtbl SysMouseWvt;

typedef struct SysMouseImpl SysMouseImpl;

typedef enum {
    WARP_DONE,   /* Warping has been done */
    WARP_NEEDED, /* Warping is needed */
    WARP_STARTED /* Warping has been done, waiting for the warp event */
} WARP_STATUS;

struct SysMouseImpl
{
    const void                     *lpVtbl;
    LONG                            ref;
    GUID                            guid;
    
    IDirectInputImpl               *dinput;
    
    /* The current data format and the conversion between internal
       and external data formats */
    DIDATAFORMAT	           *df;
    DataFormat                     *wine_df;
    int                             offset_array[WINE_INTERNALMOUSE_NUM_OBJS];
    
    /* SysMouseAImpl */
    BYTE                            absolute;
    /* Previous position for relative moves */
    LONG			    prevX, prevY;
    /* These are used in case of relative -> absolute transitions */
    POINT                           org_coords;
    HHOOK                           hook;
    HWND			    win;
    DWORD			    dwCoopLevel;
    POINT      			    mapped_center;
    DWORD			    win_centerX, win_centerY;
    LPDIDEVICEOBJECTDATA 	    data_queue;
    int				    queue_head, queue_tail, queue_len;
    BOOL			    overflow;
    /* warping: whether we need to move mouse back to middle once we
     * reach window borders (for e.g. shooters, "surface movement" games) */
    WARP_STATUS		            need_warp;
    int				    acquired;
    HANDLE			    hEvent;
    CRITICAL_SECTION		    crit;
    
    /* This is for mouse reporting. */
    Wine_InternalMouseData          m_state;
};

/* FIXME: This is ugly and not thread safe :/ */
static IDirectInputDevice8A* current_lock = NULL;

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

static void fill_mouse_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version) {
    DWORD dwSize;
    DIDEVICEINSTANCEA ddi;
    
    dwSize = lpddi->dwSize;

    TRACE("%ld %p\n", dwSize, lpddi);
    
    memset(lpddi, 0, dwSize);
    memset(&ddi, 0, sizeof(ddi));

    ddi.dwSize = dwSize;
    ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */
    ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
    if (version >= 0x0800)
        ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
    else
        ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
    strcpy(ddi.tszInstanceName, "Mouse");
    strcpy(ddi.tszProductName, "Wine Mouse");

    memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
}

static void fill_mouse_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version) {
    DWORD dwSize;
    DIDEVICEINSTANCEW ddi;
    
    dwSize = lpddi->dwSize;

    TRACE("%ld %p\n", dwSize, lpddi);
    
    memset(lpddi, 0, dwSize);
    memset(&ddi, 0, sizeof(ddi));

    ddi.dwSize = dwSize;
    ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */
    ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
    if (version >= 0x0800)
        ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
    else
        ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
    MultiByteToWideChar(CP_ACP, 0, "Mouse", -1, ddi.tszInstanceName, MAX_PATH);
    MultiByteToWideChar(CP_ACP, 0, "Wine Mouse", -1, ddi.tszProductName, MAX_PATH);

    memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
}

static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
{
    if (id != 0)
        return FALSE;

    if ((dwDevType == 0) ||
	((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) ||
	(((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) {
	TRACE("Enumerating the mouse device\n");
	
	fill_mouse_dideviceinstanceA(lpddi, version);
	
	return TRUE;
    }
    
    return FALSE;
}

static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
{
    if (id != 0)
        return FALSE;

    if ((dwDevType == 0) ||
	((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) ||
	(((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) {
	TRACE("Enumerating the mouse device\n");
	
	fill_mouse_dideviceinstanceW(lpddi, version);
	
	return TRUE;
    }
    
    return FALSE;
}

static SysMouseImpl *alloc_device(REFGUID rguid, const void *mvt, IDirectInputImpl *dinput)
{
    int offset_array[WINE_INTERNALMOUSE_NUM_OBJS] = {
	FIELD_OFFSET(Wine_InternalMouseData, lX),
	FIELD_OFFSET(Wine_InternalMouseData, lY),
	FIELD_OFFSET(Wine_InternalMouseData, lZ),
	FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 0,
	FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 1,
	FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 2
    };
    SysMouseImpl* newDevice;
    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseImpl));
    newDevice->ref = 1;
    newDevice->lpVtbl = mvt;
    InitializeCriticalSection(&(newDevice->crit));
    memcpy(&(newDevice->guid),rguid,sizeof(*rguid));

    /* Per default, Wine uses its internal data format */
    newDevice->df = (DIDATAFORMAT *) &Wine_InternalMouseFormat;
    memcpy(newDevice->offset_array, offset_array, WINE_INTERNALMOUSE_NUM_OBJS * sizeof(int));
    newDevice->wine_df = HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat));
    newDevice->wine_df->size = 0;
    newDevice->wine_df->internal_format_size = Wine_InternalMouseFormat.dwDataSize;
    newDevice->wine_df->dt = NULL;
    newDevice->dinput = dinput;

    return newDevice;
}

static HRESULT mousedev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
{
    if ((IsEqualGUID(&GUID_SysMouse,rguid)) ||             /* Generic Mouse */
	(IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
	if ((riid == NULL) ||
	    IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
	    IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
	    IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
	    IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
	    *pdev = (IDirectInputDeviceA*) alloc_device(rguid, &SysMouseAvt, dinput);
	    TRACE("Creating a Mouse device (%p)\n", *pdev);
	    return DI_OK;
	} else
	    return DIERR_NOINTERFACE;
    }
    
    return DIERR_DEVICENOTREG;
}

static HRESULT mousedev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
{
    if ((IsEqualGUID(&GUID_SysMouse,rguid)) ||             /* Generic Mouse */
	(IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
	if ((riid == NULL) ||
	    IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
	    IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
	    IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
	    IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
	    *pdev = (IDirectInputDeviceW*) alloc_device(rguid, &SysMouseWvt, dinput);
	    TRACE("Creating a Mouse device (%p)\n", *pdev);
	    return DI_OK;
	} else
	    return DIERR_NOINTERFACE;
    }
    
    return DIERR_DEVICENOTREG;
}

const struct dinput_device mouse_device = {
    "Wine mouse driver",
    mousedev_enum_deviceA,
    mousedev_enum_deviceW,
    mousedev_create_deviceA,
    mousedev_create_deviceW
};

/******************************************************************************
 *	SysMouseA (DInput Mouse support)
 */

/******************************************************************************
  *     Release : release the mouse buffer.
  */
static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    ULONG ref;
 
    ref = InterlockedDecrement(&(This->ref));
    if (ref)
	return ref;
    
    /* Free the data queue */
    HeapFree(GetProcessHeap(),0,This->data_queue);
    
    if (This->hook) {
	UnhookWindowsHookEx( This->hook );
	if (This->dwCoopLevel & DISCL_EXCLUSIVE)
            ShowCursor(TRUE); /* show cursor */
    }
    DeleteCriticalSection(&(This->crit));
    
    /* Free the DataFormat */
    if (This->df != &(Wine_InternalMouseFormat)) {
	HeapFree(GetProcessHeap(), 0, This->df->rgodf);
	HeapFree(GetProcessHeap(), 0, This->df);
    }
    
    HeapFree(GetProcessHeap(),0,This);
    return 0;
}


/******************************************************************************
  *     SetCooperativeLevel : store the window in which we will do our
  *   grabbing.
  */
static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
	LPDIRECTINPUTDEVICE8A iface,HWND hwnd,DWORD dwflags
)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    
    TRACE("(this=%p,%p,0x%08lx)\n",This,hwnd,dwflags);
    
    if (TRACE_ON(dinput)) {
	TRACE(" cooperative level : ");
	_dump_cooperativelevel_DI(dwflags);
    }
    
    /* Store the window which asks for the mouse */
    if (!hwnd)
	hwnd = GetDesktopWindow();
    This->win = hwnd;
    This->dwCoopLevel = dwflags;
    
    return DI_OK;
}


/******************************************************************************
  *     SetDataFormat : the application can choose the format of the data
  *   the device driver sends back with GetDeviceState.
  *
  *   For the moment, only the "standard" configuration (c_dfDIMouse) is supported
  *   in absolute and relative mode.
  */
static HRESULT WINAPI SysMouseAImpl_SetDataFormat(
	LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df
)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    
    TRACE("(this=%p,%p)\n",This,df);
    
    _dump_DIDATAFORMAT(df);
    
    /* Tests under windows show that a call to SetDataFormat always sets the mouse
       in relative mode whatever the dwFlags value (DIDF_ABSAXIS/DIDF_RELAXIS).
       To switch in absolute mode, SetProperty must be used. */
    This->absolute = 0;
    
    /* Store the new data format */
    This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize);
    memcpy(This->df, df, df->dwSize);
    This->df->rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize);
    memcpy(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize);
    
    /* Prepare all the data-conversion filters */
    This->wine_df = create_DataFormat(&(Wine_InternalMouseFormat), df, This->offset_array);
    
    return DI_OK;
}

/* low-level mouse hook */
static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lparam )
{
    LRESULT ret;
    MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
    SysMouseImpl* This = (SysMouseImpl*) current_lock;
    DWORD dwCoop;
    static long last_event = 0;
    int wdata;

    if (code != HC_ACTION) return CallNextHookEx( This->hook, code, wparam, lparam );

    EnterCriticalSection(&(This->crit));
    dwCoop = This->dwCoopLevel;

    /* Only allow mouse events every 10 ms.
     * This is to allow the cursor to start acceleration before
     * the warps happen. But if it involves a mouse button event we
     * allow it since we don't want to lose the clicks.
     */
    if (((GetCurrentTime() - last_event) < 10)
        && wparam == WM_MOUSEMOVE)
	goto end;
    else last_event = GetCurrentTime();
    
    /* Mouse moved -> send event if asked */
    if (This->hEvent)
        SetEvent(This->hEvent);
    
    if (wparam == WM_MOUSEMOVE) {
	if (This->absolute) {
	    if (hook->pt.x != This->prevX)
		GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x, hook->time, 0);
	    if (hook->pt.y != This->prevY)
		GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y, hook->time, 0);
	} else {
	    /* Now, warp handling */
	    if ((This->need_warp == WARP_STARTED) &&
		(hook->pt.x == This->mapped_center.x) && (hook->pt.y == This->mapped_center.y)) {
		/* Warp has been done... */
		This->need_warp = WARP_DONE;
		goto end;
	    }
	    
	    /* Relative mouse input with absolute mouse event : the real fun starts here... */
	    if ((This->need_warp == WARP_NEEDED) ||
		(This->need_warp == WARP_STARTED)) {
		if (hook->pt.x != This->prevX)
		    GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x - This->prevX,
			      hook->time, (This->dinput->evsequence)++);
		if (hook->pt.y != This->prevY)
		    GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y - This->prevY,
			      hook->time, (This->dinput->evsequence)++);
	    } else {
		/* This is the first time the event handler has been called after a
		   GetDeviceData or GetDeviceState. */
		if (hook->pt.x != This->mapped_center.x) {
		    GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x - This->mapped_center.x,
			      hook->time, (This->dinput->evsequence)++);
		    This->need_warp = WARP_NEEDED;
		}
		
		if (hook->pt.y != This->mapped_center.y) {
		    GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y - This->mapped_center.y,
			      hook->time, (This->dinput->evsequence)++);
		    This->need_warp = WARP_NEEDED;
		}
	    }
	}
	
	This->prevX = hook->pt.x;
	This->prevY = hook->pt.y;
	
	if (This->absolute) {
	    This->m_state.lX = hook->pt.x;
	    This->m_state.lY = hook->pt.y;
	} else {
	    This->m_state.lX = hook->pt.x - This->mapped_center.x;
	    This->m_state.lY = hook->pt.y - This->mapped_center.y;
	}
    }
    
    TRACE(" msg %x pt %ld %ld (W=%d)\n",
          wparam, hook->pt.x, hook->pt.y, (!This->absolute) && This->need_warp );
    
    switch(wparam) {
        case WM_LBUTTONDOWN:
	    GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0x80,
		      hook->time, This->dinput->evsequence++);
	    This->m_state.rgbButtons[0] = 0x80;
	    break;
	case WM_LBUTTONUP:
	    GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0x00,
		      hook->time, This->dinput->evsequence++);
	    This->m_state.rgbButtons[0] = 0x00;
	    break;
	case WM_RBUTTONDOWN:
	    GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0x80,
		      hook->time, This->dinput->evsequence++);
	    This->m_state.rgbButtons[1] = 0x80;
	    break;
	case WM_RBUTTONUP:
	    GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0x00,
		      hook->time, This->dinput->evsequence++);
	    This->m_state.rgbButtons[1] = 0x00;
	    break;
	case WM_MBUTTONDOWN:
	    GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0x80,
		      hook->time, This->dinput->evsequence++);
	    This->m_state.rgbButtons[2] = 0x80;
	    break;
	case WM_MBUTTONUP:
	    GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0x00,
		      hook->time, This->dinput->evsequence++);
	    This->m_state.rgbButtons[2] = 0x00;
	    break;
	case WM_MOUSEWHEEL:
	    wdata = (short)HIWORD(hook->mouseData);
	    GEN_EVENT(This->offset_array[WINE_MOUSE_Z_POSITION], wdata,
		      hook->time, This->dinput->evsequence++);
	    This->m_state.lZ += wdata;
	    break;
    }
    
    TRACE("(X: %ld - Y: %ld   L: %02x M: %02x R: %02x)\n",
	  This->m_state.lX, This->m_state.lY,
	  This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]);
    
  end:
    LeaveCriticalSection(&(This->crit));
    
    if (dwCoop & DISCL_NONEXCLUSIVE) {
	/* Pass the events down to previous handlers (e.g. win32 input) */
	ret = CallNextHookEx( This->hook, code, wparam, lparam );
    } else {
	/* Ignore message */
	ret = 1;
    }
    return ret;
}


static void dinput_window_check(SysMouseImpl* This) {
    RECT rect;
    DWORD centerX, centerY;
    
    /* make sure the window hasn't moved */
    GetWindowRect(This->win, &rect);
    centerX = (rect.right  - rect.left) / 2;
    centerY = (rect.bottom - rect.top ) / 2;
    if (This->win_centerX != centerX || This->win_centerY != centerY) {
	This->win_centerX = centerX;
	This->win_centerY = centerY;
    }
    This->mapped_center.x = This->win_centerX;
    This->mapped_center.y = This->win_centerY;
    MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1);
}


/******************************************************************************
  *     Acquire : gets exclusive control of the mouse
  */
static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    RECT  rect;
    POINT point;
    
    TRACE("(this=%p)\n",This);
    
    if (This->acquired)
      return S_FALSE;
    
    This->acquired = 1;

    /* Store (in a global variable) the current lock */
    current_lock = (IDirectInputDevice8A*)This;
    
    /* Init the mouse state */
    GetCursorPos( &point );
    if (This->absolute) {
      This->m_state.lX = point.x;
      This->m_state.lY = point.y;
      This->prevX = point.x;
      This->prevY = point.y;
    } else {
      This->m_state.lX = 0;
      This->m_state.lY = 0;
      This->org_coords = point;
    }
    This->m_state.lZ = 0;
    This->m_state.rgbButtons[0] = GetKeyState(VK_LBUTTON) & 0x80;
    This->m_state.rgbButtons[1] = GetKeyState(VK_RBUTTON) & 0x80;
    This->m_state.rgbButtons[2] = GetKeyState(VK_MBUTTON) & 0x80;
    
    /* Install our mouse hook */
    if (This->dwCoopLevel & DISCL_EXCLUSIVE)
      ShowCursor(FALSE); /* hide cursor */
    This->hook = SetWindowsHookExA( WH_MOUSE_LL, dinput_mouse_hook, DINPUT_instance, 0 );
    
    /* Get the window dimension and find the center */
    GetWindowRect(This->win, &rect);
    This->win_centerX = (rect.right  - rect.left) / 2;
    This->win_centerY = (rect.bottom - rect.top ) / 2;
    
    /* Warp the mouse to the center of the window */
    if (This->absolute == 0) {
      This->mapped_center.x = This->win_centerX;
      This->mapped_center.y = This->win_centerY;
      MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1);
      TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y);
      SetCursorPos( This->mapped_center.x, This->mapped_center.y );
#ifdef MOUSE_HACK
      This->need_warp = WARP_DONE;
#else
      This->need_warp = WARP_STARTED;
#endif
    }
	
    return DI_OK;
}

/******************************************************************************
  *     Unacquire : frees the mouse
  */
static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    
    TRACE("(this=%p)\n",This);
    
    if (0 == This->acquired) {
	return DI_NOEFFECT;
    }
	
    /* Reinstall previous mouse event handler */
    if (This->hook) {
      UnhookWindowsHookEx( This->hook );
      This->hook = 0;
      
      if (This->dwCoopLevel & DISCL_EXCLUSIVE)
	ShowCursor(TRUE); /* show cursor */
    }
	
    /* No more locks */
    if (current_lock == (IDirectInputDevice8A*) This)
      current_lock = NULL;
    else
      ERR("this(%p) != current_lock(%p)\n", This, current_lock);

    /* Unacquire device */
    This->acquired = 0;
    
    /* And put the mouse cursor back where it was at acquire time */
    if (This->absolute == 0) {
      TRACE(" warping mouse back to (%ld , %ld)\n", This->org_coords.x, This->org_coords.y);
      SetCursorPos(This->org_coords.x, This->org_coords.y);
    }
	
    return DI_OK;
}

/******************************************************************************
  *     GetDeviceState : returns the "state" of the mouse.
  *
  *   For the moment, only the "standard" return structure (DIMOUSESTATE) is
  *   supported.
  */
static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
	LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr
) {
    SysMouseImpl *This = (SysMouseImpl *)iface;

    if(This->acquired == 0) return DIERR_NOTACQUIRED;

    EnterCriticalSection(&(This->crit));
    TRACE("(this=%p,0x%08lx,%p):\n", This, len, ptr);
    TRACE("(X: %ld - Y: %ld - Z: %ld  L: %02x M: %02x R: %02x)\n",
	  This->m_state.lX, This->m_state.lY, This->m_state.lZ,
	  This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]);
    
    /* Copy the current mouse state */
    fill_DataFormat(ptr, &(This->m_state), This->wine_df);
    
    /* Initialize the buffer when in relative mode */
    if (This->absolute == 0) {
	This->m_state.lX = 0;
	This->m_state.lY = 0;
	This->m_state.lZ = 0;
    }
    
    /* Check if we need to do a mouse warping */
    if (This->need_warp == WARP_NEEDED) {
	dinput_window_check(This);
	TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y);
	SetCursorPos( This->mapped_center.x, This->mapped_center.y );
	
#ifdef MOUSE_HACK
	This->need_warp = WARP_DONE;
#else
	This->need_warp = WARP_STARTED;
#endif
    }
    
    LeaveCriticalSection(&(This->crit));
    
    return DI_OK;
}

/******************************************************************************
  *     GetDeviceData : gets buffered input data.
  */
static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,
						  DWORD dodsize,
						  LPDIDEVICEOBJECTDATA dod,
						  LPDWORD entries,
						  DWORD flags
) {
    SysMouseImpl *This = (SysMouseImpl *)iface;
    DWORD len;
    int nqtail = 0;
    
    TRACE("(%p)->(dods=%ld,dod=%p,entries=%p (%ld)%s,fl=0x%08lx%s)\n",This,dodsize,dod,
	  entries, *entries,*entries == INFINITE ? " (INFINITE)" : "",
	  flags, (flags & DIGDD_PEEK) ? " (DIGDD_PEEK)": "" );
    
    if (This->acquired == 0) {
	WARN(" application tries to get data from an unacquired device !\n");
	return DIERR_NOTACQUIRED;
    }
    
    EnterCriticalSection(&(This->crit));

    len = ((This->queue_head < This->queue_tail) ? This->queue_len : 0)
	+ (This->queue_head - This->queue_tail);
    if ((*entries != INFINITE) && (len > *entries)) len = *entries;
    
    if (dod == NULL) {
	*entries = len;
	
	if (!(flags & DIGDD_PEEK)) {
	    if (len)
		TRACE("Application discarding %ld event(s).\n", len);
	    
	    nqtail = This->queue_tail + len;
	    while (nqtail >= This->queue_len) nqtail -= This->queue_len;
	} else {
	    TRACE("Telling application that %ld event(s) are in the queue.\n", len);
	}
    } else {
	if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3)) {
	    ERR("Wrong structure size !\n");
	    LeaveCriticalSection(&(This->crit));
	    return DIERR_INVALIDPARAM;
	}
	
	if (len)
	    TRACE("Application retrieving %ld event(s):\n", len);
	
	*entries = 0;
	nqtail = This->queue_tail;
	while (len) {
	    /* Copy the buffered data into the application queue */
	    TRACE(" - queuing Offs:%2ld Data:%5ld TS:%8ld Seq:%8ld at address %p from queue tail %4d\n",
		  (This->data_queue)->dwOfs,
		  (This->data_queue)->dwData,
		  (This->data_queue)->dwTimeStamp,
		  (This->data_queue)->dwSequence,
		  (char *)dod + *entries * dodsize,
		  nqtail);
	    memcpy((char *)dod + *entries * dodsize, This->data_queue + nqtail, dodsize);
	    /* Advance position */
	    nqtail++;
	    if (nqtail >= This->queue_len)
                nqtail -= This->queue_len;
	    (*entries)++;
	    len--;
	}
    }
    if (!(flags & DIGDD_PEEK))
	This->queue_tail = nqtail;
    
    LeaveCriticalSection(&(This->crit));
    
    /* Check if we need to do a mouse warping */
    if (This->need_warp == WARP_NEEDED) {
	dinput_window_check(This);
	TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y);
	SetCursorPos( This->mapped_center.x, This->mapped_center.y );
	
#ifdef MOUSE_HACK
	This->need_warp = WARP_DONE;
#else
	This->need_warp = WARP_STARTED;
#endif
    }
    return DI_OK;
}

/******************************************************************************
  *     SetProperty : change input device properties
  */
static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
					    REFGUID rguid,
					    LPCDIPROPHEADER ph)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    
    TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
    
    if (!HIWORD(rguid)) {
	switch (LOWORD(rguid)) {
	    case (DWORD) DIPROP_BUFFERSIZE: {
		LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
		
		TRACE("buffersize = %ld\n",pd->dwData);
		
		This->data_queue = HeapAlloc(GetProcessHeap(),0, pd->dwData * sizeof(DIDEVICEOBJECTDATA));
		This->queue_head = 0;
		This->queue_tail = 0;
		This->queue_len  = pd->dwData;
		break;
	    }
	    case (DWORD) DIPROP_AXISMODE: {
		LPCDIPROPDWORD    pd = (LPCDIPROPDWORD)ph;
		This->absolute = !(pd->dwData);
		TRACE("Using %s coordinates mode now\n", This->absolute ? "absolute" : "relative");
		break;
	    }
	    default:
	      FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
	      break;
	}
    }
    
    return DI_OK;
}

/******************************************************************************
  *     GetProperty : get input device properties
  */
static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
						REFGUID rguid,
						LPDIPROPHEADER pdiph)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    
    TRACE("(this=%p,%s,%p)\n",
	  iface, debugstr_guid(rguid), pdiph);
    
    if (TRACE_ON(dinput))
	_dump_DIPROPHEADER(pdiph);
    
    if (!HIWORD(rguid)) {
	switch (LOWORD(rguid)) {
	    case (DWORD) DIPROP_BUFFERSIZE: {
		LPDIPROPDWORD	pd = (LPDIPROPDWORD)pdiph;
		
		TRACE(" return buffersize = %d\n",This->queue_len);
		pd->dwData = This->queue_len;
		break;
	    }
	      
	    case (DWORD) DIPROP_GRANULARITY: {
		LPDIPROPDWORD pr = (LPDIPROPDWORD) pdiph;
		
		/* We'll just assume that the app asks about the Z axis */
		pr->dwData = WHEEL_DELTA;
		
		break;
	    }
	      
	    case (DWORD) DIPROP_RANGE: {
		LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
		
		if ((pdiph->dwHow == DIPH_BYID) &&
		    ((pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS)) ||
		     (pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS)))) {
		    /* Querying the range of either the X or the Y axis.  As I do
		       not know the range, do as if the range were
		       unrestricted...*/
		    pr->lMin = DIPROPRANGE_NOMIN;
		    pr->lMax = DIPROPRANGE_NOMAX;
		}
		
		break;
	    }
	      
	    default:
	      FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
	      break;
	  }
      }
    
    return DI_OK;
}



/******************************************************************************
  *     SetEventNotification : specifies event to be sent on state change
  */
static HRESULT WINAPI SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE8A iface,
							 HANDLE hnd) {
    SysMouseImpl *This = (SysMouseImpl *)iface;
    
    TRACE("(this=%p,%p)\n",This,hnd);
    
    This->hEvent = hnd;
    
    return DI_OK;
}

/******************************************************************************
  *     GetCapabilities : get the device capablitites
  */
static HRESULT WINAPI SysMouseAImpl_GetCapabilities(
	LPDIRECTINPUTDEVICE8A iface,
	LPDIDEVCAPS lpDIDevCaps)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    DIDEVCAPS devcaps;

    TRACE("(this=%p,%p)\n",This,lpDIDevCaps);

    if ((lpDIDevCaps->dwSize != sizeof(DIDEVCAPS)) && (lpDIDevCaps->dwSize != sizeof(DIDEVCAPS_DX3))) {
        WARN("invalid parameter\n");
        return DIERR_INVALIDPARAM;
    }

    devcaps.dwSize = lpDIDevCaps->dwSize;
    devcaps.dwFlags = DIDC_ATTACHED;
    if (This->dinput->dwVersion >= 0x0800)
	devcaps.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
    else
	devcaps.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
    devcaps.dwAxes = 3;
    devcaps.dwButtons = 3;
    devcaps.dwPOVs = 0;
    devcaps.dwFFSamplePeriod = 0;
    devcaps.dwFFMinTimeResolution = 0;
    devcaps.dwFirmwareRevision = 100;
    devcaps.dwHardwareRevision = 100;
    devcaps.dwFFDriverVersion = 0;

    memcpy(lpDIDevCaps, &devcaps, lpDIDevCaps->dwSize);
    
    return DI_OK;
}


/******************************************************************************
  *     EnumObjects : enumerate the different buttons and axis...
  */
static HRESULT WINAPI SysMouseAImpl_EnumObjects(
	LPDIRECTINPUTDEVICE8A iface,
	LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
	LPVOID lpvRef,
	DWORD dwFlags)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    DIDEVICEOBJECTINSTANCEA ddoi;
    
    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);
    
    /* In a mouse, we have : two relative axis and three buttons */
    if ((dwFlags == DIDFT_ALL) ||
	(dwFlags & DIDFT_AXIS)) {
	/* X axis */
	ddoi.guidType = GUID_XAxis;
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_X_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS;
	strcpy(ddoi.tszName, "X-Axis");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
	
	/* Y axis */
	ddoi.guidType = GUID_YAxis;
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_Y_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS;
	strcpy(ddoi.tszName, "Y-Axis");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
	
	/* Z axis */
	ddoi.guidType = GUID_ZAxis;
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_Z_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS;
	strcpy(ddoi.tszName, "Z-Axis");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
    }

    if ((dwFlags == DIDFT_ALL) ||
	(dwFlags & DIDFT_BUTTON)) {
	ddoi.guidType = GUID_Button;
	
	/* Left button */
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_L_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE) | DIDFT_PSHBUTTON;
	strcpy(ddoi.tszName, "Left-Button");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
	
	/* Right button */
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_R_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE) | DIDFT_PSHBUTTON;
	strcpy(ddoi.tszName, "Right-Button");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
	
	/* Middle button */
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_M_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE) | DIDFT_PSHBUTTON;
	strcpy(ddoi.tszName, "Middle-Button");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
    }
    
    return DI_OK;
}

static HRESULT WINAPI SysMouseWImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface, LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,	LPVOID lpvRef,DWORD dwFlags)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    
    device_enumobjects_AtoWcb_data data;
    
    data.lpCallBack = lpCallback;
    data.lpvRef = lpvRef;
    
    return SysMouseAImpl_EnumObjects((LPDIRECTINPUTDEVICE8A) This, (LPDIENUMDEVICEOBJECTSCALLBACKA) DIEnumDevicesCallbackAtoW, (LPVOID) &data, dwFlags);
}

/******************************************************************************
  *     GetDeviceInfo : get information about a device's identity
  */
static HRESULT WINAPI SysMouseAImpl_GetDeviceInfo(
	LPDIRECTINPUTDEVICE8A iface,
	LPDIDEVICEINSTANCEA pdidi)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    TRACE("(this=%p,%p)\n", This, pdidi);

    if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA)) {
        WARN(" dinput3 not supporte yet...\n");
	return DI_OK;
    }

    fill_mouse_dideviceinstanceA(pdidi, This->dinput->dwVersion);
    
    return DI_OK;
}

static HRESULT WINAPI SysMouseWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW pdidi)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    TRACE("(this=%p,%p)\n", This, pdidi);

    if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW)) {
        WARN(" dinput3 not supporte yet...\n");
	return DI_OK;
    }

    fill_mouse_dideviceinstanceW(pdidi, This->dinput->dwVersion);
    
    return DI_OK;
}


static const IDirectInputDevice8AVtbl SysMouseAvt =
{
    IDirectInputDevice2AImpl_QueryInterface,
    IDirectInputDevice2AImpl_AddRef,
    SysMouseAImpl_Release,
    SysMouseAImpl_GetCapabilities,
    SysMouseAImpl_EnumObjects,
    SysMouseAImpl_GetProperty,
    SysMouseAImpl_SetProperty,
    SysMouseAImpl_Acquire,
    SysMouseAImpl_Unacquire,
    SysMouseAImpl_GetDeviceState,
    SysMouseAImpl_GetDeviceData,
    SysMouseAImpl_SetDataFormat,
    SysMouseAImpl_SetEventNotification,
    SysMouseAImpl_SetCooperativeLevel,
    IDirectInputDevice2AImpl_GetObjectInfo,
    SysMouseAImpl_GetDeviceInfo,
    IDirectInputDevice2AImpl_RunControlPanel,
    IDirectInputDevice2AImpl_Initialize,
    IDirectInputDevice2AImpl_CreateEffect,
    IDirectInputDevice2AImpl_EnumEffects,
    IDirectInputDevice2AImpl_GetEffectInfo,
    IDirectInputDevice2AImpl_GetForceFeedbackState,
    IDirectInputDevice2AImpl_SendForceFeedbackCommand,
    IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
    IDirectInputDevice2AImpl_Escape,
    IDirectInputDevice2AImpl_Poll,
    IDirectInputDevice2AImpl_SendDeviceData,
    IDirectInputDevice7AImpl_EnumEffectsInFile,
    IDirectInputDevice7AImpl_WriteEffectToFile,
    IDirectInputDevice8AImpl_BuildActionMap,
    IDirectInputDevice8AImpl_SetActionMap,
    IDirectInputDevice8AImpl_GetImageInfo
};

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

static const IDirectInputDevice8WVtbl SysMouseWvt =
{
    IDirectInputDevice2WImpl_QueryInterface,
    XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
    XCAST(Release)SysMouseAImpl_Release,
    XCAST(GetCapabilities)SysMouseAImpl_GetCapabilities,
    SysMouseWImpl_EnumObjects,
    XCAST(GetProperty)SysMouseAImpl_GetProperty,
    XCAST(SetProperty)SysMouseAImpl_SetProperty,
    XCAST(Acquire)SysMouseAImpl_Acquire,
    XCAST(Unacquire)SysMouseAImpl_Unacquire,
    XCAST(GetDeviceState)SysMouseAImpl_GetDeviceState,
    XCAST(GetDeviceData)SysMouseAImpl_GetDeviceData,
    XCAST(SetDataFormat)SysMouseAImpl_SetDataFormat,
    XCAST(SetEventNotification)SysMouseAImpl_SetEventNotification,
    XCAST(SetCooperativeLevel)SysMouseAImpl_SetCooperativeLevel,
    IDirectInputDevice2WImpl_GetObjectInfo,
    SysMouseWImpl_GetDeviceInfo,
    XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
    XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
    XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
    IDirectInputDevice2WImpl_EnumEffects,
    IDirectInputDevice2WImpl_GetEffectInfo,
    XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState,
    XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
    XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
    XCAST(Escape)IDirectInputDevice2AImpl_Escape,
    XCAST(Poll)IDirectInputDevice2AImpl_Poll,
    XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
    IDirectInputDevice7WImpl_EnumEffectsInFile,
    IDirectInputDevice7WImpl_WriteEffectToFile,
    IDirectInputDevice8WImpl_BuildActionMap,
    IDirectInputDevice8WImpl_SetActionMap,
    IDirectInputDevice8WImpl_GetImageInfo
};
#undef XCAST
