|
|
/*****************************************************************************
* * PidOp.c * * Copyright (c) 1999 Microsoft Corporation. All Rights Reserved. * * Abstract: * * PID device Operation . * *****************************************************************************/ #include "pidpr.h"
#define sqfl ( sqflOp )
#pragma BEGIN_CONST_DATA
static PIDUSAGE c_rgUsgGain[] = { MAKE_PIDUSAGE(DEVICE_GAIN, 0x0 ) };
static PIDREPORT DeviceGain = { HidP_Output, HID_USAGE_PAGE_PID, HID_USAGE_PID_DEVICE_GAIN_REPORT, cbX(DWORD), cA(c_rgUsgGain), c_rgUsgGain };
PIDUSAGE c_rgUsgOperationReport[] = { MAKE_PIDUSAGE(LOOP_COUNT, 0x0), };
static PIDREPORT OperationReport = { HidP_Output, HID_USAGE_PAGE_PID, HID_USAGE_PID_EFFECT_OPERATION_REPORT, cbX(DWORD), cA(c_rgUsgOperationReport), c_rgUsgOperationReport };
static PIDREPORT DeviceControlReport = { HidP_Output, HID_USAGE_PAGE_PID, HID_USAGE_PID_DEVICE_CONTROL, 0x0, 0x0, NULL };
#pragma END_CONST_DATA
STDMETHODIMP PID_EffectOperation ( IDirectInputEffectDriver *ped, DWORD dwId, DWORD dwEffect, DWORD dwMode, DWORD dwCount, BOOL bBlocking, UINT blockNr, UINT totalBlocks ) { CPidDrv *this = (CPidDrv *)ped; HRESULT hres = S_OK;
EnterProcI( PID_EffectOperation, (_"xxxxx", ped, dwId, dwEffect, dwMode, dwCount ));
hres = PID_ValidateEffectIndex(ped, dwEffect); // Allocate Memory for the report
if( SUCCEEDED(hres) ) { USHORT cbReport; PUCHAR pReport;
USHORT LinkCollection; AssertF(OperationReport.HidP_Type == HidP_Output);
cbReport = this->cbReport[OperationReport.HidP_Type]; pReport = this->pReport[OperationReport.HidP_Type];
PID_GetLinkCollectionIndex(ped, OperationReport.UsagePage, OperationReport.Collection, 0x0, &LinkCollection ); // Set the Effect Structure
if( SUCCEEDED(hres) ) { ZeroBuf(pReport, cbReport);
// Set Effect Operation
if( SUCCEEDED(hres) ) { USAGE Usage; USAGE UsagePage; NTSTATUS ntStat; UINT nUsages = 0x1; USAGE LinkCollection0; PEFFECTSTATE pEffectState = PeffectStateFromBlockIndex(this,dwEffect);
UsagePage = OperationReport.UsagePage;
PID_GetLinkCollectionIndex(ped, OperationReport.UsagePage, HID_USAGE_PID_EFFECT_OPERATION, 0x0, &LinkCollection0);
if( dwMode & DIES_SOLO ) { Usage = HID_USAGE_PID_OP_EFFECT_START_SOLO; pEffectState->lEfState |= PID_EFFECT_STARTED_SOLO; } else if( dwMode & PID_DIES_START ) { Usage = HID_USAGE_PID_OP_EFFECT_START; pEffectState->lEfState |= PID_EFFECT_STARTED; } else if(dwMode & PID_DIES_STOP ) { Usage = HID_USAGE_PID_OP_EFFECT_STOP; pEffectState->lEfState &= ~(PID_EFFECT_STARTED | PID_EFFECT_STARTED_SOLO); } else { SquirtSqflPtszV(sqfl | sqflError, TEXT("%s: FAIL Could not understand dwMode=0x%x"), s_tszProc, dwMode );
hres = E_NOTIMPL; }
ntStat = HidP_SetUsages ( OperationReport.HidP_Type, UsagePage, LinkCollection0, &Usage, &nUsages, this->ppd, pReport, cbReport);
if( FAILED(hres) ) { SquirtSqflPtszV(sqfl | sqflBenign, TEXT("%s: FAIL HidP_SetUsages:0x%x for(%x,%x,%x:%s)"), s_tszProc, ntStat, LinkCollection0, UsagePage, Usage, PIDUSAGETXT(UsagePage,Usage) ); } else { SquirtSqflPtszV(sqfl | sqflVerbose, TEXT("%s: HidP_SetUsages:0x%x for(%x,%x,%x:%s)"), s_tszProc, ntStat, LinkCollection0, UsagePage, Usage, PIDUSAGETXT(UsagePage,Usage) ); } }
// Set the Loop Count
if( SUCCEEDED(hres) ) { PID_PackValue ( ped, &OperationReport, LinkCollection, &dwCount, cbX(dwCount), pReport, cbReport );
// Set the Block Index
PID_PackValue ( ped, &g_BlockIndex, LinkCollection, &dwEffect, cbX(dwEffect), pReport, cbReport ); }
if( SUCCEEDED(hres) ) { hres = PID_SendReport(ped, pReport, cbReport, OperationReport.HidP_Type, bBlocking, blockNr, totalBlocks); } } } ExitOleProc(); return hres; }
/*****************************************************************************
* * PID_SetGain * * Set the overall device gain. * * dwId * * The joystick ID number being used. * * dwGain * * The new gain value. * * If the value is out of range for the device, the device * should use the nearest supported value and return * DI_TRUNCATED. * * Returns: * * * S_OK if the operation completed successfully. * * DI_TRUNCATED if the value was out of range and was * changed to the nearest supported value. * * Any DIERR_* error code may be returned. * * Private driver-specific error codes in the range * DIERR_DRIVERFIRST through DIERR_DRIVERLAST * may be returned. * *****************************************************************************/ STDMETHODIMP PID_SetGain ( IDirectInputEffectDriver *ped, DWORD dwId, DWORD dwGain ) { CPidDrv *this = (CPidDrv *)ped; HRESULT hres = S_OK;
EnterProc( PID_SetGain, (_"xxx", ped, dwId, dwGain)); DllEnterCrit();
// Allocate Memory for the report
if( SUCCEEDED(hres) ) { USHORT cbReport; PUCHAR pReport;
USHORT LinkCollection;
AssertF(DeviceGain.HidP_Type == HidP_Output); cbReport = this->cbReport[DeviceGain.HidP_Type]; pReport = this->pReport[DeviceGain.HidP_Type];
PID_GetLinkCollectionIndex(ped, DeviceGain.UsagePage, DeviceGain.Collection, 0x0, &LinkCollection ); // Set the Effect Structure
if( SUCCEEDED(hres) ) { ZeroBuf(pReport, cbReport);
// Set the Loop Count
if( SUCCEEDED(hres) ) { hres = PID_PackValue ( ped, &DeviceGain, LinkCollection, &dwGain, cbX(dwGain), pReport, cbReport ); }
if( SUCCEEDED(hres) ) { hres = PID_SendReport(ped, pReport, cbReport, DeviceGain.HidP_Type, FALSE, 0, 1); } } } DllLeaveCrit();
ExitOleProc(); return hres; }
/*****************************************************************************
* * PID_SendForceFeedbackCommand * * Send a command to the device. * * dwId * * The external joystick number being addressed. * * dwCommand * * A DISFFC_* value specifying the command to send. * * Returns: * * S_OK on success. * * Any DIERR_* error code may be returned. * * Private driver-specific error codes in the range * DIERR_DRIVERFIRST through DIERR_DRIVERLAST * may be returned. * *****************************************************************************/ STDMETHODIMP PID_SendForceFeedbackCommand ( IDirectInputEffectDriver *ped, DWORD dwId, DWORD dwCommand ) { CPidDrv *this = (CPidDrv *)ped; HRESULT hres = S_OK; USAGE Usages[6]; PUSAGE pUsages = &Usages[0]; UINT nUsages;
EnterProcI( PID_SendForceFeedbackCommand, (_"xxx", ped, dwId, dwCommand));
DllEnterCrit();
if( dwCommand & DISFFC_RESET ) { DWORD indx; *pUsages++ = HID_USAGE_PID_DC_DEVICE_RESET; for(indx = 1 ; (indx <= this->cMaxEffects) && (((PUNITSTATE)(g_pshmem + this->iUnitStateOffset))->cEfDownloaded != 0x0 ); indx++ ) { PID_DestroyEffect(ped, dwId, indx); } this->dwState = DIGFFS_STOPPED; } if( dwCommand & DISFFC_STOPALL ) { *pUsages++ = HID_USAGE_PID_DC_STOP_ALL_EFFECTS; this->dwState = DIGFFS_STOPPED; } if( dwCommand & DISFFC_PAUSE ) { *pUsages++ = HID_USAGE_PID_DC_DEVICE_PAUSE; } if( dwCommand & DISFFC_CONTINUE ) { *pUsages++ = HID_USAGE_PID_DC_DEVICE_CONTINUE; } if( dwCommand & DISFFC_SETACTUATORSON) { *pUsages++ = HID_USAGE_PID_DC_ENABLE_ACTUATORS; } if(dwCommand & DISFFC_SETACTUATORSOFF) { *pUsages++ = HID_USAGE_PID_DC_DISABLE_ACTUATORS; }
nUsages = (UINT)(pUsages - &Usages[0]); if(nUsages == 0x0 ) { hres = E_NOTIMPL; SquirtSqflPtszV(sqfl | sqflError, TEXT("%s: FAIL Do not understand dwCommand(0x%x) "), s_tszProc, dwCommand); }
if( SUCCEEDED(hres) ) { USHORT cbReport; PUCHAR pReport; USHORT LinkCollection;
AssertF(DeviceControlReport.HidP_Type == HidP_Output);
cbReport = this->cbReport[DeviceControlReport.HidP_Type]; pReport = this->pReport[DeviceControlReport.HidP_Type];
PID_GetLinkCollectionIndex(ped, DeviceControlReport.UsagePage, DeviceControlReport.Collection, 0x0, &LinkCollection ); // Set the Effect Structure
if( SUCCEEDED(hres) ) { USHORT UsagePage; NTSTATUS ntStat; ZeroBuf(pReport, cbReport); UsagePage = OperationReport.UsagePage;
ntStat = HidP_SetUsages ( OperationReport.HidP_Type, UsagePage, LinkCollection, &Usages[0], &nUsages, this->ppd, pReport, cbReport);
if( FAILED(ntStat) ) { SquirtSqflPtszV(sqfl | sqflError, TEXT("%s: FAIL HidP_SetUsages:0x%x for(%x,%x,%x:%s)"), s_tszProc, ntStat, LinkCollection, UsagePage, Usages[0], PIDUSAGETXT(UsagePage,Usages[0]) ); hres = ntStat; } else { SquirtSqflPtszV(sqfl | sqflVerbose, TEXT("%s: HidP_SetUsages:0x%x for(%x,%x,%x:%s)"), s_tszProc, ntStat, LinkCollection,UsagePage, Usages[0], PIDUSAGETXT(UsagePage,Usages[0]) ); }
if( SUCCEEDED(hres) ) { hres = PID_SendReport(ped, pReport, cbReport, OperationReport.HidP_Type, TRUE, 0, 1); //we block on this call
} } }
DllLeaveCrit();
ExitOleProc(); return hres; }
|