4072b224fda308d77a305a7255830a4ce686e087
[reactos.git] / dll / win32 / syssetup / proppage.c
1 /*
2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/syssetup/proppage.c
5 * PURPOSE: Property page providers
6 * PROGRAMMERS: Copyright 2018 Eric Kohl <eric.kohl@reactos.org>
7 */
8
9 #include "precomp.h"
10
11 #define NDEBUG
12 #include <debug.h>
13
14 typedef struct _MOUSE_INFO
15 {
16 HKEY hDeviceKey;
17 DWORD dwSampleRateIndex;
18 DWORD dwWheelDetection;
19 DWORD dwInputBufferLength;
20 DWORD dwInitPolled;
21 } MOUSE_INFO, *PMOUSE_INFO;
22
23 DWORD MouseSampleRates[] = {20, 40, 60, 80, 100, 200};
24
25 #define DEFAULT_SAMPLERATEINDEX 4
26 #define DEFAULT_WHEELDETECTION 2
27 #define DEFAULT_INPUTBUFFERSIZE 100
28 #define DEFAULT_MINBUFFERSIZE 100
29 #define DEFAULT_MAXBUFFERSIZE 300
30
31 /*
32 * @implemented
33 */
34 BOOL
35 WINAPI
36 CdromPropPageProvider(
37 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
38 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
39 _In_ LPARAM lParam)
40 {
41 DPRINT("CdromPropPageProvider(%p %p %lx)\n",
42 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
43 return FALSE;
44 }
45
46
47 /*
48 * @implemented
49 */
50 BOOL
51 WINAPI
52 DiskPropPageProvider(
53 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
54 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
55 _In_ LPARAM lParam)
56 {
57 DPRINT("DiskPropPageProvider(%p %p %lx)\n",
58 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
59 return FALSE;
60 }
61
62
63 /*
64 * @implemented
65 */
66 BOOL
67 WINAPI
68 EisaUpHalPropPageProvider(
69 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
70 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
71 _In_ LPARAM lParam)
72 {
73 DPRINT("EisaUpHalPropPageProvider(%p %p %lx)\n",
74 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
75 return FALSE;
76 }
77
78
79 /*
80 * @unimplemented
81 */
82 BOOL
83 WINAPI
84 LegacyDriverPropPageProvider(
85 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
86 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
87 _In_ LPARAM lParam)
88 {
89 DPRINT1("LegacyDriverPropPageProvider(%p %p %lx)\n",
90 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
91 UNIMPLEMENTED;
92 return FALSE;
93 }
94
95
96 static
97 DWORD
98 MouseGetSampleRateIndex(
99 DWORD dwSampleRate)
100 {
101 DWORD i;
102
103 for (i = 0; i < ARRAYSIZE(MouseSampleRates); i++)
104 {
105 if (MouseSampleRates[i] == dwSampleRate)
106 return i;
107 }
108
109 return DEFAULT_SAMPLERATEINDEX;
110 }
111
112
113 static
114 BOOL
115 MouseOnDialogInit(
116 HWND hwndDlg,
117 LPARAM lParam)
118 {
119 PMOUSE_INFO pMouseInfo;
120 WCHAR szBuffer[64];
121 UINT i;
122 DWORD dwType, dwSize;
123 DWORD dwSampleRate;
124 LONG lError;
125
126 /* Get the pointer to the mouse info struct */
127 pMouseInfo = (PMOUSE_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
128 if (pMouseInfo == NULL)
129 return FALSE;
130
131 /* Keep the pointer to the mouse info struct */
132 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pMouseInfo);
133
134 /* Add the sample rates */
135 for (i = 0; i < ARRAYSIZE(MouseSampleRates); i++)
136 {
137 wsprintf(szBuffer, L"%lu", MouseSampleRates[i]);
138 SendDlgItemMessageW(hwndDlg,
139 IDC_PS2MOUSESAMPLERATE,
140 CB_ADDSTRING,
141 0,
142 (LPARAM)szBuffer);
143 }
144
145 /* Read the SampleRate parameter */
146 dwSize = sizeof(DWORD);
147 lError = RegQueryValueExW(pMouseInfo->hDeviceKey,
148 L"SampleRate",
149 NULL,
150 &dwType,
151 (LPBYTE)&dwSampleRate,
152 &dwSize);
153 if (lError == ERROR_SUCCESS && dwType == REG_DWORD && dwSize == sizeof(DWORD))
154 {
155 pMouseInfo->dwSampleRateIndex = MouseGetSampleRateIndex(dwSampleRate);
156 }
157 else
158 {
159 /* Set the default sample rate (100 samples per second) */
160 pMouseInfo->dwSampleRateIndex = DEFAULT_SAMPLERATEINDEX;
161 }
162
163 /* Set the sample rate */
164 SendDlgItemMessageW(hwndDlg,
165 IDC_PS2MOUSESAMPLERATE,
166 CB_SETCURSEL,
167 pMouseInfo->dwSampleRateIndex,
168 0);
169
170 /* Add the detection options */
171 for (i = IDS_DETECTIONDISABLED; i <= IDS_ASSUMEPRESENT; i++)
172 {
173 LoadStringW(hDllInstance, i, szBuffer, ARRAYSIZE(szBuffer));
174 SendDlgItemMessageW(hwndDlg,
175 IDC_PS2MOUSEWHEEL,
176 CB_ADDSTRING,
177 0,
178 (LPARAM)szBuffer);
179 }
180
181 /* Read the EnableWheelDetection parameter */
182 dwSize = sizeof(DWORD);
183 lError = RegQueryValueExW(pMouseInfo->hDeviceKey,
184 L"EnableWheelDetection",
185 NULL,
186 &dwType,
187 (LPBYTE)&pMouseInfo->dwWheelDetection,
188 &dwSize);
189 if (lError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD))
190 {
191 /* Set the default wheel detection parameter */
192 pMouseInfo->dwWheelDetection = DEFAULT_WHEELDETECTION;
193 }
194
195 /* Set the wheel detection parameter */
196 SendDlgItemMessageW(hwndDlg,
197 IDC_PS2MOUSEWHEEL,
198 CB_SETCURSEL,
199 pMouseInfo->dwWheelDetection,
200 0);
201
202 /* Set the input buffer length range: 100-300 */
203 SendDlgItemMessageW(hwndDlg,
204 IDC_PS2MOUSEINPUTUPDN,
205 UDM_SETRANGE32,
206 DEFAULT_MINBUFFERSIZE,
207 DEFAULT_MAXBUFFERSIZE);
208
209 /* Read the MouseDataQueueSize parameter */
210 dwSize = sizeof(DWORD);
211 lError = RegQueryValueExW(pMouseInfo->hDeviceKey,
212 L"MouseDataQueueSize",
213 NULL,
214 &dwType,
215 (LPBYTE)&pMouseInfo->dwInputBufferLength,
216 &dwSize);
217 if (lError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD))
218 {
219 /* Set the default input buffer length (100 packets) */
220 pMouseInfo->dwInputBufferLength = DEFAULT_INPUTBUFFERSIZE;
221 }
222
223 /* Set the input buffer length */
224 SendDlgItemMessageW(hwndDlg,
225 IDC_PS2MOUSEINPUTUPDN,
226 UDM_SETPOS32,
227 0,
228 pMouseInfo->dwInputBufferLength);
229
230 /* Read the MouseInitializePolled parameter */
231 dwSize = sizeof(DWORD);
232 lError = RegQueryValueExW(pMouseInfo->hDeviceKey,
233 L"MouseInitializePolled",
234 NULL,
235 &dwType,
236 (LPBYTE)&pMouseInfo->dwInitPolled,
237 &dwSize);
238 if (lError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD))
239 {
240 /* Set the default init polled value (FALSE) */
241 pMouseInfo->dwInitPolled = 0;
242 }
243
244 /* Set the fast initialization option */
245 SendDlgItemMessage(hwndDlg,
246 IDC_PS2MOUSEFASTINIT,
247 BM_SETCHECK,
248 (pMouseInfo->dwInitPolled == 0) ? BST_CHECKED : 0,
249 0);
250
251 return TRUE;
252 }
253
254
255 static
256 VOID
257 MouseOnCommand(
258 HWND hwndDlg,
259 WPARAM wParam,
260 LPARAM lParam)
261 {
262 switch (LOWORD(wParam))
263 {
264 case IDC_PS2MOUSESAMPLERATE:
265 case IDC_PS2MOUSEWHEEL:
266 case IDC_PS2MOUSEINPUTLEN:
267 case IDC_PS2MOUSEFASTINIT:
268 if (HIWORD(wParam) == CBN_SELCHANGE ||
269 HIWORD(wParam) == CBN_EDITCHANGE)
270 {
271 /* Enable the Apply button */
272 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
273 }
274 break;
275
276 case IDC_PS2MOUSEDEFAULTS:
277 if (HIWORD(wParam) == BN_CLICKED)
278 {
279 /* Sample rate: 100 */
280 SendDlgItemMessageW(hwndDlg,
281 IDC_PS2MOUSESAMPLERATE,
282 CB_SETCURSEL,
283 DEFAULT_SAMPLERATEINDEX,
284 0);
285
286 /* Wheel detection: Assume wheel present */
287 SendDlgItemMessageW(hwndDlg,
288 IDC_PS2MOUSEWHEEL,
289 CB_SETCURSEL,
290 DEFAULT_WHEELDETECTION,
291 0);
292
293 /* Input buffer length: 100 packets */
294 SendDlgItemMessageW(hwndDlg,
295 IDC_PS2MOUSEINPUTUPDN,
296 UDM_SETPOS32,
297 0,
298 DEFAULT_INPUTBUFFERSIZE);
299
300 /* Fast Initialization: Checked */
301 SendDlgItemMessage(hwndDlg,
302 IDC_PS2MOUSEFASTINIT,
303 BM_SETCHECK,
304 (WPARAM)BST_CHECKED,
305 (LPARAM)0);
306
307 /* Enable the Apply button */
308 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
309 }
310 break;
311
312 default:
313 break;
314 }
315 }
316
317
318 static
319 VOID
320 MouseOnApply(
321 HWND hwndDlg)
322 {
323 PMOUSE_INFO pMouseInfo;
324 DWORD dwSampleRateIndex = 0;
325 DWORD dwSampleRate, dwWheelDetection;
326 DWORD dwInputBufferLength;
327 DWORD dwInitPolled;
328 UINT uValue;
329 BOOL bFailed;
330 INT nIndex;
331
332 pMouseInfo = (PMOUSE_INFO)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
333
334 /* Get the sample rate setting and store it if it was changed */
335 nIndex = SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSESAMPLERATE,
336 CB_GETCURSEL, 0, 0);
337 if (nIndex == CB_ERR)
338 dwSampleRateIndex = DEFAULT_SAMPLERATEINDEX;
339 else
340 dwSampleRateIndex = (DWORD)nIndex;
341
342 if (dwSampleRateIndex != pMouseInfo->dwSampleRateIndex)
343 {
344 dwSampleRate = MouseSampleRates[dwSampleRateIndex];
345 RegSetValueExW(pMouseInfo->hDeviceKey,
346 L"SampleRate",
347 0,
348 REG_DWORD,
349 (LPBYTE)&dwSampleRate,
350 sizeof(dwSampleRate));
351 }
352
353 /* Get the wheel detection setting and store it if it was changed */
354 nIndex = SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSEWHEEL,
355 CB_GETCURSEL, 0, 0);
356 if (nIndex == CB_ERR)
357 dwWheelDetection = DEFAULT_WHEELDETECTION;
358 else
359 dwWheelDetection = (DWORD)nIndex;
360
361 if (dwWheelDetection != pMouseInfo->dwWheelDetection)
362 {
363 RegSetValueExW(pMouseInfo->hDeviceKey,
364 L"EnableWheelDetection",
365 0,
366 REG_DWORD,
367 (LPBYTE)&dwWheelDetection,
368 sizeof(dwWheelDetection));
369 }
370
371 /* Get the input buffer length setting and store it if it was changed */
372 uValue = SendDlgItemMessageW(hwndDlg,
373 IDC_PS2MOUSEINPUTUPDN,
374 UDM_GETPOS32,
375 0,
376 (LPARAM)&bFailed);
377 if (bFailed)
378 dwInputBufferLength = DEFAULT_INPUTBUFFERSIZE;
379 else
380 dwInputBufferLength = (DWORD)uValue;
381
382 if (dwInputBufferLength != pMouseInfo->dwInputBufferLength)
383 {
384 RegSetValueExW(pMouseInfo->hDeviceKey,
385 L"MouseDataQueueSize",
386 0,
387 REG_DWORD,
388 (LPBYTE)&dwInputBufferLength,
389 sizeof(dwInputBufferLength));
390 }
391
392 /* Get the fast initialization setting and store it if it was changed */
393 uValue = SendDlgItemMessage(hwndDlg,
394 IDC_PS2MOUSEFASTINIT,
395 BM_GETCHECK,
396 0,
397 0);
398 dwInitPolled = (uValue == BST_CHECKED) ? 0 : 1;
399
400 if (dwInitPolled != pMouseInfo->dwInitPolled)
401 {
402 RegSetValueExW(pMouseInfo->hDeviceKey,
403 L"MouseInitializePolled",
404 0,
405 REG_DWORD,
406 (LPBYTE)&dwInitPolled,
407 sizeof(dwInitPolled));
408 }
409 }
410
411
412 static
413 BOOL
414 MouseOnNotify(
415 HWND hwndDlg,
416 WPARAM wParam,
417 LPARAM lParam)
418 {
419 switch (((LPNMHDR)lParam)->code)
420 {
421 case UDN_DELTAPOS:
422 if (((LPNMHDR)lParam)->idFrom == IDC_PS2MOUSEINPUTUPDN)
423 {
424 ((LPNMUPDOWN)lParam)->iDelta *= 10;
425 return FALSE;
426 }
427 break;
428
429 case PSN_APPLY:
430 MouseOnApply(hwndDlg);
431 return TRUE;
432 }
433
434 return FALSE;
435 }
436
437
438 static
439 INT_PTR
440 MouseOnCtrlColorStatic(
441 HWND hwndDlg,
442 WPARAM wParam,
443 LPARAM lParam)
444 {
445 if ((HWND)lParam != GetDlgItem(hwndDlg, IDC_PS2MOUSEINPUTLEN))
446 return 0;
447
448 SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
449 SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
450 return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
451 }
452
453
454 static
455 INT_PTR
456 CALLBACK
457 MouseDlgProc(
458 HWND hwndDlg,
459 UINT uMsg,
460 WPARAM wParam,
461 LPARAM lParam)
462 {
463 DPRINT("MouseDlgProc\n");
464
465 switch (uMsg)
466 {
467 case WM_INITDIALOG:
468 return MouseOnDialogInit(hwndDlg, lParam);
469
470 case WM_COMMAND:
471 MouseOnCommand(hwndDlg, wParam, lParam);
472 break;
473
474 case WM_NOTIFY:
475 return MouseOnNotify(hwndDlg, wParam, lParam);
476
477 case WM_CTLCOLORSTATIC:
478 return MouseOnCtrlColorStatic(hwndDlg, wParam, lParam);
479 }
480
481 return FALSE;
482 }
483
484
485 static
486 UINT
487 CALLBACK
488 MouseCallback(
489 HWND hWnd,
490 UINT uMsg,
491 LPPROPSHEETPAGE ppsp)
492 {
493 if (uMsg == PSPCB_RELEASE)
494 {
495 HeapFree(GetProcessHeap(), 0, (PMOUSE_INFO)ppsp->lParam);
496 }
497
498 return 1;
499 }
500
501
502 /*
503 * @implemented
504 */
505 BOOL
506 WINAPI
507 PS2MousePropPageProvider(
508 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
509 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
510 _In_ LPARAM lParam)
511 {
512 PROPSHEETPAGEW PropSheetPage;
513 HPROPSHEETPAGE hPropSheetPage;
514 PMOUSE_INFO pMouseInfo;
515
516 DPRINT("PS2MousePropPageProvider(%p %p %lx)\n",
517 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
518
519 if (lpPropSheetPageRequest->PageRequested != SPPSR_ENUM_ADV_DEVICE_PROPERTIES)
520 return FALSE;
521
522 pMouseInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MOUSE_INFO));
523 if (pMouseInfo == NULL)
524 return FALSE;
525
526 pMouseInfo->hDeviceKey = SetupDiOpenDevRegKey(lpPropSheetPageRequest->DeviceInfoSet,
527 lpPropSheetPageRequest->DeviceInfoData,
528 DICS_FLAG_GLOBAL,
529 0,
530 DIREG_DEV,
531 KEY_ALL_ACCESS);
532 if (pMouseInfo->hDeviceKey == INVALID_HANDLE_VALUE)
533 {
534 DPRINT1("SetupDiOpenDevRegKey() failed (Error %lu)\n", GetLastError());
535 HeapFree(GetProcessHeap(), 0, pMouseInfo);
536 return FALSE;
537 }
538
539 PropSheetPage.dwSize = sizeof(PROPSHEETPAGEW);
540 PropSheetPage.dwFlags = 0;
541 PropSheetPage.hInstance = hDllInstance;
542 PropSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_PS2MOUSEPROPERTIES);
543 PropSheetPage.pfnDlgProc = MouseDlgProc;
544 PropSheetPage.lParam = (LPARAM)pMouseInfo;
545 PropSheetPage.pfnCallback = MouseCallback;
546
547 hPropSheetPage = CreatePropertySheetPageW(&PropSheetPage);
548 if (hPropSheetPage == NULL)
549 {
550 DPRINT1("CreatePropertySheetPageW() failed!\n");
551 HeapFree(GetProcessHeap(), 0, pMouseInfo);
552 return FALSE;
553 }
554
555 if (!(*lpfnAddPropSheetPageProc)(hPropSheetPage, lParam))
556 {
557 DPRINT1("lpfnAddPropSheetPageProc() failed!\n");
558 DestroyPropertySheetPage(hPropSheetPage);
559 HeapFree(GetProcessHeap(), 0, pMouseInfo);
560 return FALSE;
561 }
562
563 return TRUE;
564 }
565
566
567 /*
568 * @implemented
569 */
570 BOOL
571 WINAPI
572 TapePropPageProvider(
573 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
574 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
575 _In_ LPARAM lParam)
576 {
577 DPRINT("TapePropPageProvider(%p %p %lx)\n",
578 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
579 return FALSE;
580 }
581
582 /* EOF */