[SYSSETUP] Read driver settings from and write them to the registry
authorEric Kohl <eric.kohl@reactos.org>
Sun, 29 Apr 2018 12:55:57 +0000 (14:55 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 29 Apr 2018 12:55:57 +0000 (14:55 +0200)
- Read the driver settings from the registry.
- Write the driver settings to the registry.
- Make the read-only edit control for the input buffer length look like a non-read-only one because it is controlled by the up-down control.

dll/win32/syssetup/proppage.c

index eb38cf9..4072b22 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+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;
     }