diff --git a/dll/win32/syssetup/proppage.c b/dll/win32/syssetup/proppage.c index eb38cf988f6..4072b224fda 100644 --- a/dll/win32/syssetup/proppage.c +++ b/dll/win32/syssetup/proppage.c @@ -11,8 +11,22 @@ #define NDEBUG #include +typedef struct _MOUSE_INFO +{ + HKEY hDeviceKey; + DWORD dwSampleRateIndex; + DWORD dwWheelDetection; + DWORD dwInputBufferLength; + DWORD dwInitPolled; +} MOUSE_INFO, *PMOUSE_INFO; + DWORD MouseSampleRates[] = {20, 40, 60, 80, 100, 200}; +#define DEFAULT_SAMPLERATEINDEX 4 +#define DEFAULT_WHEELDETECTION 2 +#define DEFAULT_INPUTBUFFERSIZE 100 +#define DEFAULT_MINBUFFERSIZE 100 +#define DEFAULT_MAXBUFFERSIZE 300 /* * @implemented @@ -80,13 +94,42 @@ LegacyDriverPropPageProvider( static -VOID +DWORD +MouseGetSampleRateIndex( + DWORD dwSampleRate) +{ + DWORD i; + + for (i = 0; i < ARRAYSIZE(MouseSampleRates); i++) + { + if (MouseSampleRates[i] == dwSampleRate) + return i; + } + + return DEFAULT_SAMPLERATEINDEX; +} + + +static +BOOL MouseOnDialogInit( HWND hwndDlg, LPARAM lParam) { + PMOUSE_INFO pMouseInfo; WCHAR szBuffer[64]; UINT i; + DWORD dwType, dwSize; + DWORD dwSampleRate; + LONG lError; + + /* Get the pointer to the mouse info struct */ + pMouseInfo = (PMOUSE_INFO)((LPPROPSHEETPAGE)lParam)->lParam; + if (pMouseInfo == NULL) + return FALSE; + + /* Keep the pointer to the mouse info struct */ + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pMouseInfo); /* Add the sample rates */ for (i = 0; i < ARRAYSIZE(MouseSampleRates); i++) @@ -99,6 +142,31 @@ MouseOnDialogInit( (LPARAM)szBuffer); } + /* Read the SampleRate parameter */ + dwSize = sizeof(DWORD); + lError = RegQueryValueExW(pMouseInfo->hDeviceKey, + L"SampleRate", + NULL, + &dwType, + (LPBYTE)&dwSampleRate, + &dwSize); + if (lError == ERROR_SUCCESS && dwType == REG_DWORD && dwSize == sizeof(DWORD)) + { + pMouseInfo->dwSampleRateIndex = MouseGetSampleRateIndex(dwSampleRate); + } + else + { + /* Set the default sample rate (100 samples per second) */ + pMouseInfo->dwSampleRateIndex = DEFAULT_SAMPLERATEINDEX; + } + + /* Set the sample rate */ + SendDlgItemMessageW(hwndDlg, + IDC_PS2MOUSESAMPLERATE, + CB_SETCURSEL, + pMouseInfo->dwSampleRateIndex, + 0); + /* Add the detection options */ for (i = IDS_DETECTIONDISABLED; i <= IDS_ASSUMEPRESENT; i++) { @@ -110,18 +178,77 @@ MouseOnDialogInit( (LPARAM)szBuffer); } + /* Read the EnableWheelDetection parameter */ + dwSize = sizeof(DWORD); + lError = RegQueryValueExW(pMouseInfo->hDeviceKey, + L"EnableWheelDetection", + NULL, + &dwType, + (LPBYTE)&pMouseInfo->dwWheelDetection, + &dwSize); + if (lError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD)) + { + /* Set the default wheel detection parameter */ + pMouseInfo->dwWheelDetection = DEFAULT_WHEELDETECTION; + } + + /* Set the wheel detection parameter */ + SendDlgItemMessageW(hwndDlg, + IDC_PS2MOUSEWHEEL, + CB_SETCURSEL, + pMouseInfo->dwWheelDetection, + 0); + /* Set the input buffer length range: 100-300 */ SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSEINPUTUPDN, UDM_SETRANGE32, - 100, - 300); + DEFAULT_MINBUFFERSIZE, + DEFAULT_MAXBUFFERSIZE); + /* Read the MouseDataQueueSize parameter */ + dwSize = sizeof(DWORD); + lError = RegQueryValueExW(pMouseInfo->hDeviceKey, + L"MouseDataQueueSize", + NULL, + &dwType, + (LPBYTE)&pMouseInfo->dwInputBufferLength, + &dwSize); + if (lError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD)) + { + /* Set the default input buffer length (100 packets) */ + pMouseInfo->dwInputBufferLength = DEFAULT_INPUTBUFFERSIZE; + } + + /* Set the input buffer length */ SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSEINPUTUPDN, UDM_SETPOS32, 0, - 100); + pMouseInfo->dwInputBufferLength); + + /* Read the MouseInitializePolled parameter */ + dwSize = sizeof(DWORD); + lError = RegQueryValueExW(pMouseInfo->hDeviceKey, + L"MouseInitializePolled", + NULL, + &dwType, + (LPBYTE)&pMouseInfo->dwInitPolled, + &dwSize); + if (lError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD)) + { + /* Set the default init polled value (FALSE) */ + pMouseInfo->dwInitPolled = 0; + } + + /* Set the fast initialization option */ + SendDlgItemMessage(hwndDlg, + IDC_PS2MOUSEFASTINIT, + BM_SETCHECK, + (pMouseInfo->dwInitPolled == 0) ? BST_CHECKED : 0, + 0); + + return TRUE; } @@ -153,14 +280,14 @@ MouseOnCommand( SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSESAMPLERATE, CB_SETCURSEL, - 4, + DEFAULT_SAMPLERATEINDEX, 0); /* Wheel detection: Assume wheel present */ SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSEWHEEL, CB_SETCURSEL, - 2, + DEFAULT_WHEELDETECTION, 0); /* Input buffer length: 100 packets */ @@ -168,7 +295,7 @@ MouseOnCommand( IDC_PS2MOUSEINPUTUPDN, UDM_SETPOS32, 0, - 100); + DEFAULT_INPUTBUFFERSIZE); /* Fast Initialization: Checked */ SendDlgItemMessage(hwndDlg, @@ -188,6 +315,100 @@ MouseOnCommand( } +static +VOID +MouseOnApply( + HWND hwndDlg) +{ + PMOUSE_INFO pMouseInfo; + DWORD dwSampleRateIndex = 0; + DWORD dwSampleRate, dwWheelDetection; + DWORD dwInputBufferLength; + DWORD dwInitPolled; + UINT uValue; + BOOL bFailed; + INT nIndex; + + pMouseInfo = (PMOUSE_INFO)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + /* Get the sample rate setting and store it if it was changed */ + nIndex = SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSESAMPLERATE, + CB_GETCURSEL, 0, 0); + if (nIndex == CB_ERR) + dwSampleRateIndex = DEFAULT_SAMPLERATEINDEX; + else + dwSampleRateIndex = (DWORD)nIndex; + + if (dwSampleRateIndex != pMouseInfo->dwSampleRateIndex) + { + dwSampleRate = MouseSampleRates[dwSampleRateIndex]; + RegSetValueExW(pMouseInfo->hDeviceKey, + L"SampleRate", + 0, + REG_DWORD, + (LPBYTE)&dwSampleRate, + sizeof(dwSampleRate)); + } + + /* Get the wheel detection setting and store it if it was changed */ + nIndex = SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSEWHEEL, + CB_GETCURSEL, 0, 0); + if (nIndex == CB_ERR) + dwWheelDetection = DEFAULT_WHEELDETECTION; + else + dwWheelDetection = (DWORD)nIndex; + + if (dwWheelDetection != pMouseInfo->dwWheelDetection) + { + RegSetValueExW(pMouseInfo->hDeviceKey, + L"EnableWheelDetection", + 0, + REG_DWORD, + (LPBYTE)&dwWheelDetection, + sizeof(dwWheelDetection)); + } + + /* Get the input buffer length setting and store it if it was changed */ + uValue = SendDlgItemMessageW(hwndDlg, + IDC_PS2MOUSEINPUTUPDN, + UDM_GETPOS32, + 0, + (LPARAM)&bFailed); + if (bFailed) + dwInputBufferLength = DEFAULT_INPUTBUFFERSIZE; + else + dwInputBufferLength = (DWORD)uValue; + + if (dwInputBufferLength != pMouseInfo->dwInputBufferLength) + { + RegSetValueExW(pMouseInfo->hDeviceKey, + L"MouseDataQueueSize", + 0, + REG_DWORD, + (LPBYTE)&dwInputBufferLength, + sizeof(dwInputBufferLength)); + } + + /* Get the fast initialization setting and store it if it was changed */ + uValue = SendDlgItemMessage(hwndDlg, + IDC_PS2MOUSEFASTINIT, + BM_GETCHECK, + 0, + 0); + dwInitPolled = (uValue == BST_CHECKED) ? 0 : 1; + + if (dwInitPolled != pMouseInfo->dwInitPolled) + { + RegSetValueExW(pMouseInfo->hDeviceKey, + L"MouseInitializePolled", + 0, + REG_DWORD, + (LPBYTE)&dwInitPolled, + sizeof(dwInitPolled)); + } +} + + static BOOL MouseOnNotify( @@ -195,21 +416,41 @@ MouseOnNotify( WPARAM wParam, LPARAM lParam) { - switch (((LPNMHDR)lParam)->idFrom) + switch (((LPNMHDR)lParam)->code) { - case IDC_PS2MOUSEINPUTUPDN: - if (((LPNMHDR)lParam)->code == UDN_DELTAPOS) + case UDN_DELTAPOS: + if (((LPNMHDR)lParam)->idFrom == IDC_PS2MOUSEINPUTUPDN) { ((LPNMUPDOWN)lParam)->iDelta *= 10; return FALSE; } break; + + case PSN_APPLY: + MouseOnApply(hwndDlg); + return TRUE; } return FALSE; } +static +INT_PTR +MouseOnCtrlColorStatic( + HWND hwndDlg, + WPARAM wParam, + LPARAM lParam) +{ + if ((HWND)lParam != GetDlgItem(hwndDlg, IDC_PS2MOUSEINPUTLEN)) + return 0; + + SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT)); + SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); + return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); +} + + static INT_PTR CALLBACK @@ -224,8 +465,7 @@ MouseDlgProc( switch (uMsg) { case WM_INITDIALOG: - MouseOnDialogInit(hwndDlg, lParam); - return TRUE; + return MouseOnDialogInit(hwndDlg, lParam); case WM_COMMAND: MouseOnCommand(hwndDlg, wParam, lParam); @@ -234,12 +474,30 @@ MouseDlgProc( case WM_NOTIFY: return MouseOnNotify(hwndDlg, wParam, lParam); + case WM_CTLCOLORSTATIC: + return MouseOnCtrlColorStatic(hwndDlg, wParam, lParam); } return FALSE; } +static +UINT +CALLBACK +MouseCallback( + HWND hWnd, + UINT uMsg, + LPPROPSHEETPAGE ppsp) +{ + if (uMsg == PSPCB_RELEASE) + { + HeapFree(GetProcessHeap(), 0, (PMOUSE_INFO)ppsp->lParam); + } + + return 1; +} + /* * @implemented @@ -253,6 +511,7 @@ PS2MousePropPageProvider( { PROPSHEETPAGEW PropSheetPage; HPROPSHEETPAGE hPropSheetPage; + PMOUSE_INFO pMouseInfo; DPRINT("PS2MousePropPageProvider(%p %p %lx)\n", lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam); @@ -260,18 +519,36 @@ PS2MousePropPageProvider( if (lpPropSheetPageRequest->PageRequested != SPPSR_ENUM_ADV_DEVICE_PROPERTIES) return FALSE; + pMouseInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MOUSE_INFO)); + if (pMouseInfo == NULL) + return FALSE; + + pMouseInfo->hDeviceKey = SetupDiOpenDevRegKey(lpPropSheetPageRequest->DeviceInfoSet, + lpPropSheetPageRequest->DeviceInfoData, + DICS_FLAG_GLOBAL, + 0, + DIREG_DEV, + KEY_ALL_ACCESS); + if (pMouseInfo->hDeviceKey == INVALID_HANDLE_VALUE) + { + DPRINT1("SetupDiOpenDevRegKey() failed (Error %lu)\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, pMouseInfo); + return FALSE; + } + PropSheetPage.dwSize = sizeof(PROPSHEETPAGEW); PropSheetPage.dwFlags = 0; PropSheetPage.hInstance = hDllInstance; PropSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_PS2MOUSEPROPERTIES); PropSheetPage.pfnDlgProc = MouseDlgProc; - PropSheetPage.lParam = 0; - PropSheetPage.pfnCallback = NULL; + PropSheetPage.lParam = (LPARAM)pMouseInfo; + PropSheetPage.pfnCallback = MouseCallback; hPropSheetPage = CreatePropertySheetPageW(&PropSheetPage); if (hPropSheetPage == NULL) { DPRINT1("CreatePropertySheetPageW() failed!\n"); + HeapFree(GetProcessHeap(), 0, pMouseInfo); return FALSE; } @@ -279,6 +556,7 @@ PS2MousePropPageProvider( { DPRINT1("lpfnAddPropSheetPageProc() failed!\n"); DestroyPropertySheetPage(hPropSheetPage); + HeapFree(GetProcessHeap(), 0, pMouseInfo); return FALSE; }