remove double comment
[reactos.git] / reactos / dll / cpl / desk / settings.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Display Control Panel
4 * FILE: lib/cpl/desk/settings.c
5 * PURPOSE: Settings property page
6 *
7 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
8 * Hervé Poussineau (hpoussin@reactos.org)
9 */
10
11 #include "desk.h"
12
13 /* As slider control can't contain user data, we have to keep an
14 * array of RESOLUTION_INFO to have our own associated data.
15 */
16 typedef struct _RESOLUTION_INFO
17 {
18 DWORD dmPelsWidth;
19 DWORD dmPelsHeight;
20 } RESOLUTION_INFO, *PRESOLUTION_INFO;
21
22 typedef struct _SETTINGS_ENTRY
23 {
24 struct _SETTINGS_ENTRY *Blink;
25 struct _SETTINGS_ENTRY *Flink;
26 DWORD dmBitsPerPel;
27 DWORD dmPelsWidth;
28 DWORD dmPelsHeight;
29 } SETTINGS_ENTRY, *PSETTINGS_ENTRY;
30
31 typedef struct _DISPLAY_DEVICE_ENTRY
32 {
33 struct _DISPLAY_DEVICE_ENTRY *Flink;
34 LPTSTR DeviceDescription;
35 LPTSTR DeviceName;
36 PSETTINGS_ENTRY Settings; /* sorted by increasing dmPelsHeight, BPP */
37 DWORD SettingsCount;
38 PRESOLUTION_INFO Resolutions;
39 DWORD ResolutionsCount;
40 PSETTINGS_ENTRY CurrentSettings; /* Points into Settings list */
41 SETTINGS_ENTRY InitialSettings;
42 } DISPLAY_DEVICE_ENTRY, *PDISPLAY_DEVICE_ENTRY;
43
44 typedef struct _GLOBAL_DATA
45 {
46 PDISPLAY_DEVICE_ENTRY DisplayDeviceList;
47 PDISPLAY_DEVICE_ENTRY CurrentDisplayDevice;
48 HBITMAP hBitmap;
49 int cxSource;
50 int cySource;
51 } GLOBAL_DATA, *PGLOBAL_DATA;
52
53 static VOID
54 UpdateDisplay(IN HWND hwndDlg, PGLOBAL_DATA pGlobalData, IN BOOL bUpdateThumb)
55 {
56 TCHAR Buffer[64];
57 TCHAR Pixel[64];
58 DWORD index;
59
60 LoadString(hApplet, IDS_PIXEL, Pixel, sizeof(Pixel) / sizeof(TCHAR));
61 _stprintf(Buffer, Pixel, pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsWidth, pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsHeight, Pixel);
62 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION_TEXT, WM_SETTEXT, 0, (LPARAM)Buffer);
63
64 for (index = 0; index < pGlobalData->CurrentDisplayDevice->ResolutionsCount; index++)
65 {
66
67 if (pGlobalData->CurrentDisplayDevice->Resolutions[index].dmPelsWidth == pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsWidth &&
68 pGlobalData->CurrentDisplayDevice->Resolutions[index].dmPelsHeight == pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsHeight)
69 {
70 if (bUpdateThumb)
71 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_SETPOS, TRUE, index);
72 break;
73 }
74 }
75 if (LoadString(hApplet, (2900 + pGlobalData->CurrentDisplayDevice->CurrentSettings->dmBitsPerPel), Buffer, sizeof(Buffer) / sizeof(TCHAR)))
76 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)Buffer);
77 }
78
79 static PSETTINGS_ENTRY
80 GetPossibleSettings(IN LPTSTR DeviceName, OUT DWORD* pSettingsCount, OUT PSETTINGS_ENTRY* CurrentSettings)
81 {
82 DEVMODE devmode;
83 DWORD NbSettings = 0;
84 DWORD iMode = 0;
85 DWORD dwFlags = 0;
86 PSETTINGS_ENTRY Settings = NULL;
87 HDC hDC;
88 PSETTINGS_ENTRY Current;
89 DWORD bpp, xres, yres, checkbpp;
90
91
92 /* Get current settings */
93 *CurrentSettings = NULL;
94 hDC = CreateIC(NULL, DeviceName, NULL, NULL);
95 bpp = GetDeviceCaps(hDC, PLANES);
96 bpp *= GetDeviceCaps(hDC, BITSPIXEL);
97 xres = GetDeviceCaps(hDC, HORZRES);
98 yres = GetDeviceCaps(hDC, VERTRES);
99 DeleteDC(hDC);
100
101 /* List all settings */
102 devmode.dmSize = (WORD)sizeof(DEVMODE);
103 devmode.dmDriverExtra = 0;
104 while (EnumDisplaySettingsEx(DeviceName, iMode, &devmode, dwFlags))
105 {
106 if (devmode.dmBitsPerPel==8 || devmode.dmBitsPerPel==16 || devmode.dmBitsPerPel==24 || devmode.dmBitsPerPel==32) checkbpp=1;
107 else checkbpp=0;
108
109 if (devmode.dmPelsWidth < 640 ||
110 devmode.dmPelsHeight < 480 || checkbpp == 0)
111 {
112 iMode++;
113 continue;
114 }
115
116 Current = HeapAlloc(GetProcessHeap(), 0, sizeof(SETTINGS_ENTRY));
117 if (Current != NULL)
118 {
119 /* Sort resolutions by increasing height, and BPP */
120 PSETTINGS_ENTRY Previous = NULL;
121 PSETTINGS_ENTRY Next = Settings;
122 Current->dmPelsWidth = devmode.dmPelsWidth;
123 Current->dmPelsHeight = devmode.dmPelsHeight;
124 Current->dmBitsPerPel = devmode.dmBitsPerPel;
125 while (Next != NULL && (
126 Next->dmPelsHeight < Current->dmPelsHeight ||
127 (Next->dmPelsHeight == Current->dmPelsHeight && Next->dmBitsPerPel < Current->dmBitsPerPel) ||
128 (Next->dmPelsHeight == Current->dmPelsHeight &&
129 Next->dmBitsPerPel == Current->dmBitsPerPel &&
130 Next->dmPelsWidth < Current->dmPelsWidth)))
131 {
132 Previous = Next;
133 Next = Next->Flink;
134 }
135 Current->Blink = Previous;
136 Current->Flink = Next;
137 if (Previous == NULL)
138 Settings = Current;
139 else
140 Previous->Flink = Current;
141 if (Next != NULL)
142 Next->Blink = Current;
143 if (devmode.dmPelsWidth == xres && devmode.dmPelsHeight == yres && devmode.dmBitsPerPel == bpp)
144 {
145 *CurrentSettings = Current;
146 }
147 NbSettings++;
148 }
149 iMode++;
150 }
151
152 *pSettingsCount = NbSettings;
153 return Settings;
154 }
155
156 static BOOL
157 AddDisplayDevice(IN PGLOBAL_DATA pGlobalData, IN LPTSTR Description, IN LPTSTR DeviceName)
158 {
159 PDISPLAY_DEVICE_ENTRY newEntry = NULL;
160 LPTSTR description = NULL;
161 LPTSTR name = NULL;
162 DWORD descriptionSize;
163 DWORD nameSize;
164 PSETTINGS_ENTRY Current;
165 DWORD ResolutionsCount = 1;
166 DWORD i;
167
168 newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(DISPLAY_DEVICE_ENTRY));
169 memset(newEntry, 0, sizeof(DISPLAY_DEVICE_ENTRY));
170 if (!newEntry) goto ByeBye;
171
172 newEntry->Settings = GetPossibleSettings(DeviceName, &newEntry->SettingsCount, &newEntry->CurrentSettings);
173 if (!newEntry->Settings) goto ByeBye;
174
175 newEntry->InitialSettings.dmPelsWidth = newEntry->CurrentSettings->dmPelsWidth;
176 newEntry->InitialSettings.dmPelsHeight = newEntry->CurrentSettings->dmPelsHeight;
177 newEntry->InitialSettings.dmBitsPerPel = newEntry->CurrentSettings->dmBitsPerPel;
178
179 /* Count different resolutions */
180 for (Current = newEntry->Settings; Current != NULL; Current = Current->Flink)
181 {
182 if (Current->Flink != NULL &&
183 ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) ||
184 (Current->dmPelsHeight != Current->Flink->dmPelsHeight)))
185 {
186 ResolutionsCount++;
187 }
188 }
189
190 newEntry->Resolutions = HeapAlloc(GetProcessHeap(), 0, ResolutionsCount * sizeof(RESOLUTION_INFO));
191 if (!newEntry->Resolutions) goto ByeBye;
192 newEntry->ResolutionsCount = ResolutionsCount;
193 /* Fill resolutions infos */
194 for (Current = newEntry->Settings, i = 0; Current != NULL; Current = Current->Flink)
195 if (Current->Flink == NULL || (Current->Flink != NULL &&
196 ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) || (Current->dmPelsHeight != Current->Flink->dmPelsHeight))))
197 {
198 newEntry->Resolutions[i].dmPelsWidth = Current->dmPelsWidth;
199 newEntry->Resolutions[i].dmPelsHeight = Current->dmPelsHeight;
200 i++;
201 }
202
203 descriptionSize = (_tcslen(Description) + 1) * sizeof(TCHAR);
204 description = HeapAlloc(GetProcessHeap(), 0, descriptionSize);
205 if (!description) goto ByeBye;
206
207 nameSize = (_tcslen(DeviceName) + 1) * sizeof(TCHAR);
208 name = HeapAlloc(GetProcessHeap(), 0, nameSize);
209 if (!name) goto ByeBye;
210
211 memcpy(description, Description, descriptionSize);
212 memcpy(name, DeviceName, nameSize);
213 newEntry->DeviceDescription = description;
214 newEntry->DeviceName = name;
215 newEntry->Flink = pGlobalData->DisplayDeviceList;
216 pGlobalData->DisplayDeviceList = newEntry;
217 return TRUE;
218
219 ByeBye:
220 if (newEntry != NULL)
221 {
222 if (newEntry->Settings != NULL)
223 {
224 Current = newEntry->Settings;
225 while (Current != NULL)
226 {
227 PSETTINGS_ENTRY Next = Current->Flink;
228 HeapFree(GetProcessHeap(), 0, Current);
229 Current = Next;
230 }
231 }
232 if (newEntry->Resolutions != NULL)
233 HeapFree(GetProcessHeap(), 0, newEntry->Resolutions);
234 HeapFree(GetProcessHeap(), 0, newEntry);
235 }
236 if (description != NULL)
237 HeapFree(GetProcessHeap(), 0, description);
238 if (name != NULL)
239 HeapFree(GetProcessHeap(), 0, name);
240 return FALSE;
241 }
242
243 static VOID
244 OnDisplayDeviceChanged(IN HWND hwndDlg, IN PGLOBAL_DATA pGlobalData, IN PDISPLAY_DEVICE_ENTRY pDeviceEntry)
245 {
246 PSETTINGS_ENTRY Current;
247 DWORD index;
248
249 pGlobalData->CurrentDisplayDevice = pDeviceEntry; /* Update global variable */
250
251 /* Fill color depths combo box */
252 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_RESETCONTENT, 0, 0);
253 for (Current = pDeviceEntry->Settings; Current != NULL; Current = Current->Flink)
254 {
255 TCHAR Buffer[64];
256 if (LoadString(hApplet, (2900 + Current->dmBitsPerPel), Buffer, sizeof(Buffer) / sizeof(TCHAR)))
257 {
258 index = (DWORD) SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)Buffer);
259 if (index == (DWORD)CB_ERR)
260 {
261 index = (DWORD) SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_ADDSTRING, 0, (LPARAM)Buffer);
262 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_SETITEMDATA, index, Current->dmBitsPerPel);
263 }
264 }
265 }
266
267 /* Fill resolutions slider */
268 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_CLEARTICS, TRUE, 0);
269 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_SETRANGE, TRUE, MAKELONG(0, pDeviceEntry->ResolutionsCount - 1));
270
271 UpdateDisplay(hwndDlg, pGlobalData, TRUE);
272 }
273
274 static VOID
275 OnInitDialog(IN HWND hwndDlg)
276 {
277 DWORD Result = 0;
278 DWORD iDevNum = 0;
279 DISPLAY_DEVICE displayDevice;
280 BITMAP bitmap;
281 PGLOBAL_DATA pGlobalData;
282
283 pGlobalData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBAL_DATA));
284 if (pGlobalData == NULL)
285 return;
286
287 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
288
289 /* Get video cards list */
290 displayDevice.cb = (DWORD)sizeof(DISPLAY_DEVICE);
291 while (EnumDisplayDevices(NULL, iDevNum, &displayDevice, 0))
292 {
293 if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0)
294 {
295 if (AddDisplayDevice(pGlobalData, displayDevice.DeviceString, displayDevice.DeviceName))
296 Result++;
297 }
298 iDevNum++;
299 }
300 if (Result == 0)
301 {
302 /* No adapter found */
303 EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_BPP), FALSE);
304 EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_RESOLUTION), FALSE);
305 EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_RESOLUTION_TEXT), FALSE);
306 EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_ADVANCED), FALSE);
307 }
308 else if (Result == 1)
309 {
310 /* Single video adapter */
311 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_DEVICE, WM_SETTEXT, 0, (LPARAM)pGlobalData->DisplayDeviceList->DeviceDescription);
312 OnDisplayDeviceChanged(hwndDlg, pGlobalData, pGlobalData->DisplayDeviceList);
313 }
314 else
315 {
316 /* FIXME: multi video adapter */
317 /* FIXME: choose selected adapter being the primary one */
318 }
319
320 pGlobalData->hBitmap = LoadImage(hApplet, MAKEINTRESOURCE(IDC_MONITOR), IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT);
321 if (pGlobalData->hBitmap != NULL)
322 {
323 GetObject(pGlobalData->hBitmap, sizeof(BITMAP), &bitmap);
324
325 pGlobalData->cxSource = bitmap.bmWidth;
326 pGlobalData->cySource = bitmap.bmHeight;
327 }
328 }
329
330 static VOID
331 OnBPPChanged(IN HWND hwndDlg, IN PGLOBAL_DATA pGlobalData)
332 {
333 /* if new BPP is not compatible with resolution:
334 * 1) try to find the nearest smaller matching resolution
335 * 2) otherwise, get the nearest bigger resolution
336 */
337 PSETTINGS_ENTRY Current;
338 DWORD dmNewBitsPerPel;
339 DWORD index;
340 TCHAR Buffer[64];
341
342 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, WM_GETTEXT, (WPARAM)(sizeof(Buffer) / sizeof(TCHAR)), (LPARAM)Buffer);
343 index = (DWORD) SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)Buffer);
344 dmNewBitsPerPel = (DWORD) SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_GETITEMDATA, index, 0);
345
346 /* find if new parameters are valid */
347 Current = pGlobalData->CurrentDisplayDevice->CurrentSettings;
348 if (dmNewBitsPerPel == Current->dmBitsPerPel)
349 {
350 /* no change */
351 return;
352 }
353
354 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
355
356 if (dmNewBitsPerPel < Current->dmBitsPerPel)
357 {
358 Current = Current->Blink;
359 while (Current != NULL)
360 {
361 if (Current->dmBitsPerPel == dmNewBitsPerPel
362 && Current->dmPelsHeight == pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsHeight
363 && Current->dmPelsWidth == pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsWidth)
364 {
365 pGlobalData->CurrentDisplayDevice->CurrentSettings = Current;
366 UpdateDisplay(hwndDlg, pGlobalData, TRUE);
367 return;
368 }
369 Current = Current->Blink;
370 }
371 }
372 else
373 {
374 Current = Current->Flink;
375 while (Current != NULL)
376 {
377 if (Current->dmBitsPerPel == dmNewBitsPerPel
378 && Current->dmPelsHeight == pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsHeight
379 && Current->dmPelsWidth == pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsWidth)
380 {
381 pGlobalData->CurrentDisplayDevice->CurrentSettings = Current;
382 UpdateDisplay(hwndDlg, pGlobalData, TRUE);
383 return;
384 }
385 Current = Current->Flink;
386 }
387 }
388
389 /* search smaller resolution compatible with current color depth */
390 Current = pGlobalData->CurrentDisplayDevice->CurrentSettings->Blink;
391 while (Current != NULL)
392 {
393 if (Current->dmBitsPerPel == dmNewBitsPerPel)
394 {
395 pGlobalData->CurrentDisplayDevice->CurrentSettings = Current;
396 UpdateDisplay(hwndDlg, pGlobalData, TRUE);
397 return;
398 }
399 Current = Current->Blink;
400 }
401
402 /* search bigger resolution compatible with current color depth */
403 Current = pGlobalData->CurrentDisplayDevice->CurrentSettings->Flink;
404 while (Current != NULL)
405 {
406 if (Current->dmBitsPerPel == dmNewBitsPerPel)
407 {
408 pGlobalData->CurrentDisplayDevice->CurrentSettings = Current;
409 UpdateDisplay(hwndDlg, pGlobalData, TRUE);
410 return;
411 }
412 Current = Current->Flink;
413 }
414
415 /* we shouldn't go there */
416 }
417
418 static VOID
419 OnResolutionChanged(IN HWND hwndDlg, IN PGLOBAL_DATA pGlobalData, IN DWORD NewPosition,
420 IN BOOL bUpdateThumb)
421 {
422 /* if new resolution is not compatible with color depth:
423 * 1) try to find the nearest bigger matching color depth
424 * 2) otherwise, get the nearest smaller color depth
425 */
426 PSETTINGS_ENTRY Current;
427 DWORD dmNewPelsHeight = pGlobalData->CurrentDisplayDevice->Resolutions[NewPosition].dmPelsHeight;
428 DWORD dmNewPelsWidth = pGlobalData->CurrentDisplayDevice->Resolutions[NewPosition].dmPelsWidth;
429
430 /* find if new parameters are valid */
431 Current = pGlobalData->CurrentDisplayDevice->CurrentSettings;
432 if (dmNewPelsHeight == Current->dmPelsHeight && dmNewPelsWidth == Current->dmPelsWidth)
433 {
434 /* no change */
435 return;
436 }
437
438 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
439
440 if (dmNewPelsHeight < Current->dmPelsHeight)
441 {
442 Current = Current->Blink;
443 while (Current != NULL)
444 {
445 if (Current->dmPelsHeight == dmNewPelsHeight
446 && Current->dmPelsWidth == dmNewPelsWidth
447 && Current->dmBitsPerPel == pGlobalData->CurrentDisplayDevice->CurrentSettings->dmBitsPerPel)
448 {
449 pGlobalData->CurrentDisplayDevice->CurrentSettings = Current;
450 UpdateDisplay(hwndDlg, pGlobalData, bUpdateThumb);
451 return;
452 }
453 Current = Current->Blink;
454 }
455 }
456 else
457 {
458 Current = Current->Flink;
459 while (Current != NULL)
460 {
461 if (Current->dmPelsHeight == dmNewPelsHeight
462 && Current->dmPelsWidth == dmNewPelsWidth
463 && Current->dmBitsPerPel == pGlobalData->CurrentDisplayDevice->CurrentSettings->dmBitsPerPel)
464 {
465 pGlobalData->CurrentDisplayDevice->CurrentSettings = Current;
466 UpdateDisplay(hwndDlg, pGlobalData, bUpdateThumb);
467 return;
468 }
469 Current = Current->Flink;
470 }
471 }
472
473 /* search bigger color depth compatible with current resolution */
474 Current = pGlobalData->CurrentDisplayDevice->CurrentSettings->Flink;
475 while (Current != NULL)
476 {
477 if (dmNewPelsHeight == Current->dmPelsHeight && dmNewPelsWidth == Current->dmPelsWidth)
478 {
479 pGlobalData->CurrentDisplayDevice->CurrentSettings = Current;
480 UpdateDisplay(hwndDlg, pGlobalData, bUpdateThumb);
481 return;
482 }
483 Current = Current->Flink;
484 }
485
486 /* search smaller color depth compatible with current resolution */
487 Current = pGlobalData->CurrentDisplayDevice->CurrentSettings->Blink;
488 while (Current != NULL)
489 {
490 if (dmNewPelsHeight == Current->dmPelsHeight && dmNewPelsWidth == Current->dmPelsWidth)
491 {
492 pGlobalData->CurrentDisplayDevice->CurrentSettings = Current;
493 UpdateDisplay(hwndDlg, pGlobalData, bUpdateThumb);
494 return;
495 }
496 Current = Current->Blink;
497 }
498
499 /* we shouldn't go there */
500 }
501
502 static VOID
503 OnAdvancedButton()
504 {
505 MessageBox(NULL, TEXT("That button doesn't do anything yet"), TEXT("Whoops"), MB_OK);
506 }
507
508 /* Property page dialog callback */
509 INT_PTR CALLBACK
510 SettingsPageProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
511 {
512 PGLOBAL_DATA pGlobalData;
513
514 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
515
516 switch(uMsg)
517 {
518 case WM_INITDIALOG:
519 OnInitDialog(hwndDlg);
520 break;
521 case WM_COMMAND:
522 {
523 DWORD controlId = LOWORD(wParam);
524 DWORD command = HIWORD(wParam);
525
526 if (controlId == IDC_SETTINGS_ADVANCED && command == BN_CLICKED)
527 OnAdvancedButton();
528 else if (controlId == IDC_SETTINGS_BPP && command == CBN_SELCHANGE)
529 OnBPPChanged(hwndDlg, pGlobalData);
530 break;
531 }
532 case WM_HSCROLL:
533 {
534 switch (LOWORD(wParam))
535 {
536 case TB_LINEUP:
537 case TB_LINEDOWN:
538 case TB_PAGEUP:
539 case TB_PAGEDOWN:
540 case TB_TOP:
541 case TB_BOTTOM:
542 case TB_ENDTRACK:
543 {
544 DWORD newPosition = (DWORD) SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_GETPOS, 0, 0);
545 OnResolutionChanged(hwndDlg, pGlobalData, newPosition, TRUE);
546 break;
547 }
548
549 case TB_THUMBTRACK:
550 OnResolutionChanged(hwndDlg, pGlobalData, HIWORD(wParam), FALSE);
551 break;
552 }
553 break;
554 }
555 case WM_NOTIFY:
556 {
557 LPNMHDR lpnm = (LPNMHDR)lParam;
558 if (lpnm->code == (UINT)PSN_APPLY)
559 {
560 if (pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsWidth != pGlobalData->CurrentDisplayDevice->InitialSettings.dmPelsWidth
561 || pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsHeight != pGlobalData->CurrentDisplayDevice->InitialSettings.dmPelsHeight
562 || pGlobalData->CurrentDisplayDevice->CurrentSettings->dmBitsPerPel != pGlobalData->CurrentDisplayDevice->InitialSettings.dmBitsPerPel)
563 {
564 /* FIXME: Need to test changes */
565 /* Apply new settings */
566 LONG rc;
567 DEVMODE devmode;
568 RtlZeroMemory(&devmode, sizeof(DEVMODE));
569 devmode.dmSize = (WORD)sizeof(DEVMODE);
570 devmode.dmPelsWidth = pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsWidth;
571 devmode.dmPelsHeight = pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsHeight;
572 devmode.dmBitsPerPel = pGlobalData->CurrentDisplayDevice->CurrentSettings->dmBitsPerPel;
573 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
574 rc = ChangeDisplaySettingsEx(
575 pGlobalData->CurrentDisplayDevice->DeviceName,
576 &devmode,
577 NULL,
578 CDS_UPDATEREGISTRY,
579 NULL);
580 switch (rc)
581 {
582 case DISP_CHANGE_SUCCESSFUL:
583 pGlobalData->CurrentDisplayDevice->InitialSettings.dmPelsWidth = pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsWidth;
584 pGlobalData->CurrentDisplayDevice->InitialSettings.dmPelsHeight = pGlobalData->CurrentDisplayDevice->CurrentSettings->dmPelsHeight;
585 pGlobalData->CurrentDisplayDevice->InitialSettings.dmBitsPerPel = pGlobalData->CurrentDisplayDevice->CurrentSettings->dmBitsPerPel;
586 break;
587 case DISP_CHANGE_FAILED:
588 MessageBox(NULL, TEXT("Failed to apply new settings..."), TEXT("Display settings"), MB_OK | MB_ICONSTOP);
589 break;
590 case DISP_CHANGE_RESTART:
591 MessageBox(NULL, TEXT("You need to restart your computer to apply changes."), TEXT("Display settings"), MB_OK | MB_ICONINFORMATION);
592 break;
593 default:
594 MessageBox(NULL, TEXT("Unknown error when applying new settings..."), TEXT("Display settings"), MB_OK | MB_ICONSTOP);
595 break;
596 }
597 }
598 }
599 break;
600 }
601
602 case WM_PAINT:
603 {
604 PAINTSTRUCT ps;
605 HDC hdc, hdcMem;
606
607 hdc = BeginPaint(hwndDlg, &ps);
608
609 hdcMem = CreateCompatibleDC(hdc);
610 SelectObject(hdcMem, pGlobalData->hBitmap);
611 /*
612 TransparentBlt(hdc, 98, 0,
613 pGlobalData->cxSource,
614 pGlobalData->cySource, hdcMem, 0, 0,
615 pGlobalData->cxSource,
616 pGlobalData->cySource, 0xFF80FF);
617 */
618 DeleteDC(hdcMem);
619 EndPaint(hwndDlg, &ps);
620
621 break;
622 }
623
624 case WM_DESTROY:
625 {
626 PDISPLAY_DEVICE_ENTRY Current = pGlobalData->DisplayDeviceList;
627 while (Current != NULL)
628 {
629 PDISPLAY_DEVICE_ENTRY Next = Current->Flink;
630 PSETTINGS_ENTRY CurrentSettings = Current->Settings;
631 while (CurrentSettings != NULL)
632 {
633 PSETTINGS_ENTRY NextSettings = CurrentSettings->Flink;
634 HeapFree(GetProcessHeap(), 0, CurrentSettings);
635 CurrentSettings = NextSettings;
636 }
637 HeapFree(GetProcessHeap(), 0, Current);
638 Current = Next;
639 }
640
641 DeleteObject(pGlobalData->hBitmap);
642
643 HeapFree(GetProcessHeap(), 0, pGlobalData);
644 }
645 }
646 return FALSE;
647 }