📄 joystick_linux.c
字号:
BOOL skip = FALSE;
switch (wine_obj) {
case 0:
ddoi.guidType = GUID_XAxis;
break;
case 1:
ddoi.guidType = GUID_YAxis;
break;
case 2:
ddoi.guidType = GUID_ZAxis;
break;
case 3:
ddoi.guidType = GUID_RxAxis;
break;
case 4:
ddoi.guidType = GUID_RyAxis;
break;
case 5:
ddoi.guidType = GUID_RzAxis;
break;
case 6:
ddoi.guidType = GUID_Slider;
break;
case 7:
ddoi.guidType = GUID_Slider;
break;
case 8:
pov[0]++;
ddoi.guidType = GUID_POV;
break;
case 9:
pov[1]++;
ddoi.guidType = GUID_POV;
break;
case 10:
pov[2]++;
ddoi.guidType = GUID_POV;
break;
case 11:
pov[3]++;
ddoi.guidType = GUID_POV;
break;
default:
ddoi.guidType = GUID_Unknown;
}
if (wine_obj < 8) {
user_offset = This->offsets[wine_obj]; /* get user offset from wine index */
user_object = offset_to_object(This, user_offset);
ddoi.dwType = This->user_df->rgodf[user_object].dwType & 0x00ffffff;
ddoi.dwOfs = This->user_df->rgodf[user_object].dwOfs;
sprintf(ddoi.tszName, "Axis %d", axes);
axes++;
} else {
if (pov[wine_obj - 8] < 2) {
user_offset = This->offsets[wine_obj]; /* get user offset from wine index */
user_object = offset_to_object(This, user_offset);
ddoi.dwType = This->user_df->rgodf[user_object].dwType & 0x00ffffff;
ddoi.dwOfs = This->user_df->rgodf[user_object].dwOfs;
sprintf(ddoi.tszName, "POV %d", povs);
povs++;
} else
skip = TRUE;
}
if (!skip) {
_dump_OBJECTINSTANCEA(&ddoi);
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE)
return DI_OK;
}
}
}
if ((dwFlags == DIDFT_ALL) ||
(dwFlags & DIDFT_BUTTON)) {
/* The DInput SDK says that GUID_Button is only for mouse buttons but well... */
ddoi.guidType = GUID_Button;
for (i = 0; i < This->buttons; i++) {
user_offset = This->offsets[i + 12]; /* get user offset from wine index */
user_object = offset_to_object(This, user_offset);
ddoi.guidType = GUID_Button;
ddoi.dwType = This->user_df->rgodf[user_object].dwType & 0x00ffffff;
ddoi.dwOfs = This->user_df->rgodf[user_object].dwOfs;
sprintf(ddoi.tszName, "Button %d", i);
_dump_OBJECTINSTANCEA(&ddoi);
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
}
}
return DI_OK;
}
/******************************************************************************
* EnumObjects : enumerate the different buttons and axis...
*/
static HRESULT WINAPI JoystickWImpl_EnumObjects(
LPDIRECTINPUTDEVICE8W iface,
LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
LPVOID lpvRef,
DWORD dwFlags)
{
JoystickImpl *This = (JoystickImpl *)iface;
device_enumobjects_AtoWcb_data data;
data.lpCallBack = lpCallback;
data.lpvRef = lpvRef;
return JoystickAImpl_EnumObjects((LPDIRECTINPUTDEVICE8A) This, (LPDIENUMDEVICEOBJECTSCALLBACKA) DIEnumDevicesCallbackAtoW, (LPVOID) &data, dwFlags);
}
/******************************************************************************
* GetProperty : get input device properties
*/
static HRESULT WINAPI JoystickAImpl_GetProperty(
LPDIRECTINPUTDEVICE8A iface,
REFGUID rguid,
LPDIPROPHEADER pdiph)
{
JoystickImpl *This = (JoystickImpl *)iface;
TRACE("(%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_RANGE: {
LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
int obj = find_property(This, pdiph);
/* The app is querying the current range of the axis
* return the lMin and lMax values */
if (obj >= 0) {
pr->lMin = This->props[obj].lMin;
pr->lMax = This->props[obj].lMax;
TRACE("range(%ld, %ld) obj=%d\n", pr->lMin, pr->lMax, obj);
return DI_OK;
}
break;
}
case (DWORD) DIPROP_DEADZONE: {
LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
int obj = find_property(This, pdiph);
if (obj >= 0) {
pd->dwData = This->props[obj].lDeadZone;
TRACE("deadzone(%ld) obj=%d\n", pd->dwData, obj);
return DI_OK;
}
break;
}
case (DWORD) DIPROP_SATURATION: {
LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
int obj = find_property(This, pdiph);
if (obj >= 0) {
pd->dwData = This->props[obj].lSaturation;
TRACE("saturation(%ld) obj=%d\n", pd->dwData, obj);
return DI_OK;
}
break;
}
default:
FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
break;
}
}
return DI_OK;
}
/******************************************************************************
* GetObjectInfo : get object info
*/
HRESULT WINAPI JoystickAImpl_GetObjectInfo(
LPDIRECTINPUTDEVICE8A iface,
LPDIDEVICEOBJECTINSTANCEA pdidoi,
DWORD dwObj,
DWORD dwHow)
{
JoystickImpl *This = (JoystickImpl *)iface;
DIDEVICEOBJECTINSTANCEA didoiA;
unsigned int i;
TRACE("(%p,%p,%ld,0x%08lx(%s))\n",
iface, pdidoi, dwObj, dwHow,
dwHow == DIPH_BYOFFSET ? "DIPH_BYOFFSET" :
dwHow == DIPH_BYID ? "DIPH_BYID" :
dwHow == DIPH_BYUSAGE ? "DIPH_BYUSAGE" :
"UNKNOWN");
if (pdidoi == NULL) {
WARN("invalid parameter: pdidoi = NULL\n");
return DIERR_INVALIDPARAM;
}
if ((pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCEA)) &&
(pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3A))) {
WARN("invalid parameter: pdidoi->dwSize = %ld != %d or %d\n",
pdidoi->dwSize, sizeof(DIDEVICEOBJECTINSTANCEA),
sizeof(DIDEVICEOBJECTINSTANCE_DX3A));
return DIERR_INVALIDPARAM;
}
ZeroMemory(&didoiA, sizeof(didoiA));
didoiA.dwSize = pdidoi->dwSize;
switch (dwHow) {
case DIPH_BYOFFSET: {
int axis = 0;
int pov = 0;
int button = 0;
for (i = 0; i < This->user_df->dwNumObjs; i++) {
if (This->user_df->rgodf[i].dwOfs == dwObj) {
if (This->user_df->rgodf[i].pguid)
didoiA.guidType = *This->user_df->rgodf[i].pguid;
else
didoiA.guidType = GUID_NULL;
didoiA.dwOfs = dwObj;
didoiA.dwType = This->user_df->rgodf[i].dwType;
didoiA.dwFlags = This->user_df->rgodf[i].dwFlags;
if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_AXIS)
sprintf(didoiA.tszName, "Axis %d", axis);
else if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_POV)
sprintf(didoiA.tszName, "POV %d", pov);
else if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_BUTTON)
sprintf(didoiA.tszName, "Button %d", button);
CopyMemory(pdidoi, &didoiA, pdidoi->dwSize);
return DI_OK;
}
if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_AXIS)
axis++;
else if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_POV)
pov++;
else if (DIDFT_GETTYPE(This->user_df->rgodf[i].dwType) & DIDFT_BUTTON)
button++;
}
break;
}
case DIPH_BYID:
FIXME("dwHow = DIPH_BYID not implemented\n");
break;
case DIPH_BYUSAGE:
FIXME("dwHow = DIPH_BYUSAGE not implemented\n");
break;
default:
WARN("invalid parameter: dwHow = %08lx\n", dwHow);
return DIERR_INVALIDPARAM;
}
CopyMemory(pdidoi, &didoiA, pdidoi->dwSize);
return DI_OK;
}
/******************************************************************************
* GetDeviceInfo : get information about a device's identity
*/
HRESULT WINAPI JoystickAImpl_GetDeviceInfo(
LPDIRECTINPUTDEVICE8A iface,
LPDIDEVICEINSTANCEA pdidi)
{
JoystickImpl *This = (JoystickImpl *)iface;
TRACE("(%p,%p)\n", iface, pdidi);
if (pdidi == NULL) {
WARN("invalid pointer\n");
return E_POINTER;
}
if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3A)) &&
(pdidi->dwSize != sizeof(DIDEVICEINSTANCEA))) {
WARN("invalid parameter: pdidi->dwSize = %ld != %d or %d\n",
pdidi->dwSize, sizeof(DIDEVICEINSTANCE_DX3A),
sizeof(DIDEVICEINSTANCEA));
return DIERR_INVALIDPARAM;
}
/* Return joystick */
pdidi->guidInstance = GUID_Joystick;
pdidi->guidProduct = DInput_Wine_Joystick_GUID;
/* we only support traditional joysticks for now */
pdidi->dwDevType = This->devcaps.dwDevType;
strcpy(pdidi->tszInstanceName, "Joystick");
strcpy(pdidi->tszProductName, This->name);
if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3A)) {
pdidi->guidFFDriver = GUID_NULL;
pdidi->wUsagePage = 0;
pdidi->wUsage = 0;
}
return DI_OK;
}
/******************************************************************************
* GetDeviceInfo : get information about a device's identity
*/
HRESULT WINAPI JoystickWImpl_GetDeviceInfo(
LPDIRECTINPUTDEVICE8W iface,
LPDIDEVICEINSTANCEW pdidi)
{
JoystickImpl *This = (JoystickImpl *)iface;
TRACE("(%p,%p)\n", iface, pdidi);
if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) &&
(pdidi->dwSize != sizeof(DIDEVICEINSTANCEW))) {
WARN("invalid parameter: pdidi->dwSize = %ld != %d or %d\n",
pdidi->dwSize, sizeof(DIDEVICEINSTANCE_DX3W),
sizeof(DIDEVICEINSTANCEW));
return DIERR_INVALIDPARAM;
}
/* Return joystick */
pdidi->guidInstance = GUID_Joystick;
pdidi->guidProduct = DInput_Wine_Joystick_GUID;
/* we only support traditional joysticks for now */
pdidi->dwDevType = This->devcaps.dwDevType;
MultiByteToWideChar(CP_ACP, 0, "Joystick", -1, pdidi->tszInstanceName, MAX_PATH);
MultiByteToWideChar(CP_ACP, 0, This->name, -1, pdidi->tszProductName, MAX_PATH);
if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3W)) {
pdidi->guidFFDriver = GUID_NULL;
pdidi->wUsagePage = 0;
pdidi->wUsage = 0;
}
return DI_OK;
}
static const IDirectInputDevice8AVtbl JoystickAvt =
{
IDirectInputDevice2AImpl_QueryInterface,
IDirectInputDevice2AImpl_AddRef,
JoystickAImpl_Release,
JoystickAImpl_GetCapabilities,
JoystickAImpl_EnumObjects,
JoystickAImpl_GetProperty,
JoystickAImpl_SetProperty,
JoystickAImpl_Acquire,
JoystickAImpl_Unacquire,
JoystickAImpl_GetDeviceState,
JoystickAImpl_GetDeviceData,
JoystickAImpl_SetDataFormat,
JoystickAImpl_SetEventNotification,
IDirectInputDevice2AImpl_SetCooperativeLevel,
JoystickAImpl_GetObjectInfo,
JoystickAImpl_GetDeviceInfo,
IDirectInputDevice2AImpl_RunControlPanel,
IDirectInputDevice2AImpl_Initialize,
IDirectInputDevice2AImpl_CreateEffect,
IDirectInputDevice2AImpl_EnumEffects,
IDirectInputDevice2AImpl_GetEffectInfo,
IDirectInputDevice2AImpl_GetForceFeedbackState,
IDirectInputDevice2AImpl_SendForceFeedbackCommand,
IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
IDirectInputDevice2AImpl_Escape,
JoystickAImpl_Poll,
IDirectInputDevice2AImpl_SendDeviceData,
IDirectInputDevice7AImpl_EnumEffectsInFile,
IDirectInputDevice7AImpl_WriteEffectToFile,
IDirectInputDevice8AImpl_BuildActionMap,
IDirectInputDevice8AImpl_SetActionMap,
IDirectInputDevice8AImpl_GetImageInfo
};
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(SysJoystickWvt.fun))
#else
# define XCAST(fun) (void*)
#endif
static const IDirectInputDevice8WVtbl SysJoystickWvt =
{
IDirectInputDevice2WImpl_QueryInterface,
XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
XCAST(Release)JoystickAImpl_Release,
XCAST(GetCapabilities)JoystickAImpl_GetCapabilities,
JoystickWImpl_EnumObjects,
XCAST(GetProperty)JoystickAImpl_GetProperty,
XCAST(SetProperty)JoystickAImpl_SetProperty,
XCAST(Acquire)JoystickAImpl_Acquire,
XCAST(Unacquire)JoystickAImpl_Unacquire,
XCAST(GetDeviceState)JoystickAImpl_GetDeviceState,
XCAST(GetDeviceData)JoystickAImpl_GetDeviceData,
XCAST(SetDataFormat)JoystickAImpl_SetDataFormat,
XCAST(SetEventNotification)JoystickAImpl_SetEventNotification,
XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
IDirectInputDevice2WImpl_GetObjectInfo,
JoystickWImpl_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)JoystickAImpl_Poll,
XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
IDirectInputDevice7WImpl_EnumEffectsInFile,
IDirectInputDevice7WImpl_WriteEffectToFile,
IDirectInputDevice8WImpl_BuildActionMap,
IDirectInputDevice8WImpl_SetActionMap,
IDirectInputDevice8WImpl_GetImageInfo
};
#undef XCAST
#else /* HAVE_LINUX_22_JOYSTICK_API */
const struct dinput_device joystick_linux_device = {
"Wine Linux joystick driver",
NULL,
NULL,
NULL,
NULL
};
#endif /* HAVE_LINUX_22_JOYSTICK_API */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -