On Tue, Mar 04, 2014 at 08:20:09PM +0100, Elias Vanderstuyft wrote:
So change in dinput/effect_linuxinput.c:488 : This->effect.u.periodic.period = tsp->dwPeriod / 1000; to : if (0 < tsp->dwPeriod && tsp->dwPeriod <= 1000) This->effect.u.periodic.period = 1; else This->effect.u.periodic.period = tsp->dwPeriod / 1000;
Seems good. While we're here, any reason not to use round(3) instead of always rounding down in the >1000 case?
b) Anticipate if dwPeriod < 0, otherwise periodic.period will incorrectly wrap around because it's unsigned. We can choose to let periodic.period be proportional to: - 0 (driver will generate EINVAL) - abs(dwPeriod) (no error, and is mathematically more correct)
DWORDs are usually treated as unsigned. Is this how Windows behaves for massive dwPeriod? I would expect E_INVALIDARG, since it's out of the range [0,36000).
So, change in dinput/effect_linuxinput.c:191 : if (dwFlags & DIEP_DURATION) { peff->dwDuration = (DWORD)This->effect.replay.length * 1000; } to : if (dwFlags & DIEP_DURATION) { peff->dwDuration = (This->effect.replay.length ?
(DWORD)This->effect.replay.length * 1000 : -1); }
And change in dinput/effect_linuxinput.c:424 : if (dwFlags & DIEP_DURATION) This->effect.replay.length = peff->dwDuration / 1000; to : if (dwFlags & DIEP_DURATION) { if (peff->dwDuration == -1) This->effect.replay.length = 0; // Infinity else if (peff->dwDuration > 1000) This->effect.replay.length = peff->dwDuration / 1000; else This->effect.replay.length = 1; // Smallest non-zero value }
This seems okay, though again, maybe use round(). You should also use INFINITE instead of -1.
Andrew