1 /*
2 rdesktop: A Remote Desktop Protocol client.
3 Connection settings dialog
4 Copyright (C) Ged Murphy 2007
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "precomp.h"
22
23 #include <winreg.h>
24 #include <commdlg.h>
25
26 #define MAX_KEY_NAME 255
27
28 HINSTANCE hInst;
29
30 static VOID ReLoadGeneralPage(PINFO pInfo);
31 static VOID ReLoadDisplayPage(PINFO pInfo);
32
33 static VOID
DoOpenFile(PINFO pInfo)34 DoOpenFile(PINFO pInfo)
35 {
36 OPENFILENAMEW ofn;
37 WCHAR szFileName[MAX_PATH] = L"Default.rdp";
38 static WCHAR szFilter[] = L"Remote Desktop Files (*.RDP)\0*.rdp\0";
39
40 ZeroMemory(&ofn, sizeof(ofn));
41 ofn.lStructSize = sizeof(OPENFILENAMEW);
42 ofn.hwndOwner = pInfo->hGeneralPage;
43 ofn.nMaxFile = MAX_PATH;
44 ofn.nMaxFileTitle = MAX_PATH;
45 ofn.lpstrDefExt = L"RDP";
46 ofn.lpstrFilter = szFilter;
47 ofn.lpstrFile = szFileName;
48 ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST;
49
50 if (GetOpenFileNameW(&ofn))
51 {
52 LoadRdpSettingsFromFile(pInfo->pRdpSettings, szFileName);
53 ReLoadGeneralPage(pInfo);
54 ReLoadDisplayPage(pInfo);
55 }
56 }
57
58
59 static VOID
DoSaveAs(PINFO pInfo)60 DoSaveAs(PINFO pInfo)
61 {
62 OPENFILENAMEW ofn;
63 WCHAR szFileName[MAX_PATH] = L"Default.rdp";
64 static WCHAR szFilter[] = L"Remote Desktop Files (*.RDP)\0*.rdp\0";
65
66 ZeroMemory(&ofn, sizeof(ofn));
67 ofn.lStructSize = sizeof(OPENFILENAMEW);
68 ofn.hwndOwner = pInfo->hGeneralPage;
69 ofn.nMaxFile = MAX_PATH;
70 ofn.nMaxFileTitle = MAX_PATH;
71 ofn.lpstrDefExt = L"RDP";
72 ofn.lpstrFilter = szFilter;
73 ofn.lpstrFile = szFileName;
74 ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
75
76 if (GetSaveFileNameW(&ofn))
77 {
78 SaveAllSettings(pInfo);
79 SaveRdpSettingsToFile(szFileName, pInfo->pRdpSettings);
80 }
81 }
82
83
84 static VOID
OnTabWndSelChange(PINFO pInfo)85 OnTabWndSelChange(PINFO pInfo)
86 {
87 switch (TabCtrl_GetCurSel(pInfo->hTab))
88 {
89 case 0: //General
90 ShowWindow(pInfo->hGeneralPage, SW_SHOW);
91 ShowWindow(pInfo->hDisplayPage, SW_HIDE);
92 BringWindowToTop(pInfo->hGeneralPage);
93 break;
94 case 1: //Display
95 ShowWindow(pInfo->hGeneralPage, SW_HIDE);
96 ShowWindow(pInfo->hDisplayPage, SW_SHOW);
97 BringWindowToTop(pInfo->hDisplayPage);
98 break;
99 }
100 }
101
102
103 static VOID
LoadUsernameHint(HWND hDlg,INT iCur)104 LoadUsernameHint(HWND hDlg, INT iCur)
105 {
106 WCHAR szValue[MAXVALUE+1000];
107 WCHAR szName[MAX_KEY_NAME];
108 WCHAR szKeyName[] = L"Software\\Microsoft\\Terminal Server Client\\Servers";
109 PWCHAR lpAddress;
110 HKEY hKey;
111 HKEY hSubKey;
112 LONG lRet = ERROR_SUCCESS;
113 INT iIndex = 0;
114 DWORD dwSize = MAX_KEY_NAME;
115
116 SendDlgItemMessageW(hDlg, IDC_SERVERCOMBO, CB_GETLBTEXT, (WPARAM)iCur, (LPARAM)szValue);
117
118 /* remove possible port number */
119 lpAddress = wcstok(szValue, L":");
120
121 if (lpAddress == NULL)
122 return;
123
124 if (RegOpenKeyExW(HKEY_CURRENT_USER,
125 szKeyName,
126 0,
127 KEY_READ,
128 &hKey) == ERROR_SUCCESS)
129 {
130 while (lRet == ERROR_SUCCESS)
131 {
132 dwSize = MAX_KEY_NAME;
133
134 lRet = RegEnumKeyExW(hKey, iIndex, szName, &dwSize, NULL, NULL, NULL, NULL);
135
136 if(lRet == ERROR_SUCCESS && wcscmp(szName, lpAddress) == 0)
137 {
138 if(RegOpenKeyExW(hKey, szName, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
139 break;
140
141 dwSize = MAXVALUE * sizeof(WCHAR);
142
143 if(RegQueryValueExW(hKey, L"UsernameHint", 0, NULL, (LPBYTE)szValue, &dwSize) == ERROR_SUCCESS)
144 {
145 SetDlgItemTextW(hDlg, IDC_NAMEEDIT, szValue);
146 }
147
148 RegCloseKey(hSubKey);
149 break;
150 }
151 iIndex++;
152 }
153 RegCloseKey(hKey);
154 }
155 }
156
157
158 static VOID
FillServerAddressCombo(PINFO pInfo)159 FillServerAddressCombo(PINFO pInfo)
160 {
161 HKEY hKey;
162 WCHAR KeyName[] = L"Software\\Microsoft\\Terminal Server Client\\Default";
163 WCHAR Name[MAX_KEY_NAME];
164 LONG ret = ERROR_SUCCESS;
165 DWORD size;
166 INT i = 0;
167 BOOL found = FALSE;
168
169 if (RegOpenKeyExW(HKEY_CURRENT_USER,
170 KeyName,
171 0,
172 KEY_READ,
173 &hKey) == ERROR_SUCCESS)
174 {
175 while (ret == ERROR_SUCCESS)
176 {
177 size = MAX_KEY_NAME;
178 ret = RegEnumValueW(hKey,
179 i,
180 Name,
181 &size,
182 NULL,
183 NULL,
184 NULL,
185 NULL);
186 if (ret == ERROR_SUCCESS)
187 {
188 size = sizeof(Name);
189 if (RegQueryValueExW(hKey,
190 Name,
191 0,
192 NULL,
193 NULL,
194 &size) == ERROR_SUCCESS)
195 {
196 LPWSTR lpAddress = HeapAlloc(GetProcessHeap(),
197 0,
198 size);
199 if (lpAddress)
200 {
201 if (RegQueryValueExW(hKey,
202 Name,
203 0,
204 NULL,
205 (LPBYTE)lpAddress,
206 &size) == ERROR_SUCCESS)
207 {
208 SendDlgItemMessageW(pInfo->hGeneralPage,
209 IDC_SERVERCOMBO,
210 CB_ADDSTRING,
211 0,
212 (LPARAM)lpAddress);
213 found = TRUE;
214 }
215
216 HeapFree(GetProcessHeap(),
217 0,
218 lpAddress);
219 }
220 }
221 }
222
223 i++;
224 }
225 RegCloseKey(hKey);
226 }
227
228 if (LoadStringW(hInst,
229 IDS_BROWSESERVER,
230 Name,
231 sizeof(Name) / sizeof(WCHAR)))
232 {
233 SendDlgItemMessageW(pInfo->hGeneralPage,
234 IDC_SERVERCOMBO,
235 CB_ADDSTRING,
236 0,
237 (LPARAM)Name);
238 }
239
240 if(found)
241 {
242 SendDlgItemMessageW(pInfo->hGeneralPage,
243 IDC_SERVERCOMBO,
244 CB_SETCURSEL,
245 0,
246 0);
247 LoadUsernameHint(pInfo->hGeneralPage, 0);
248 }
249
250 }
251
252
253 static VOID
ReLoadGeneralPage(PINFO pInfo)254 ReLoadGeneralPage(PINFO pInfo)
255 {
256 LPWSTR lpText;
257
258 /* add file address */
259 lpText = GetStringFromSettings(pInfo->pRdpSettings,
260 L"full address");
261 if (lpText)
262 {
263 SetDlgItemTextW(pInfo->hGeneralPage,
264 IDC_SERVERCOMBO,
265 lpText);
266 }
267
268 /* set user name */
269 lpText = GetStringFromSettings(pInfo->pRdpSettings,
270 L"username");
271 if (lpText)
272 {
273 SetDlgItemTextW(pInfo->hGeneralPage,
274 IDC_NAMEEDIT,
275 lpText);
276 }
277 }
278
279
280 static VOID
GeneralOnInit(HWND hwnd,PINFO pInfo)281 GeneralOnInit(HWND hwnd,
282 PINFO pInfo)
283 {
284 SetWindowLongPtrW(hwnd,
285 GWLP_USERDATA,
286 (LONG_PTR)pInfo);
287
288 pInfo->hGeneralPage = hwnd;
289
290 SetWindowPos(pInfo->hGeneralPage,
291 NULL,
292 2,
293 22,
294 0,
295 0,
296 SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
297
298 pInfo->hLogon = LoadImageW(hInst,
299 MAKEINTRESOURCEW(IDI_LOGON),
300 IMAGE_ICON,
301 32,
302 32,
303 LR_DEFAULTCOLOR);
304 if (pInfo->hLogon)
305 {
306 SendDlgItemMessageW(pInfo->hGeneralPage,
307 IDC_LOGONICON,
308 STM_SETICON,
309 (WPARAM)pInfo->hLogon,
310 0);
311 }
312
313 pInfo->hConn = LoadImageW(hInst,
314 MAKEINTRESOURCEW(IDI_CONN),
315 IMAGE_ICON,
316 32,
317 32,
318 LR_DEFAULTCOLOR);
319 if (pInfo->hConn)
320 {
321 SendDlgItemMessageW(pInfo->hGeneralPage,
322 IDC_CONNICON,
323 STM_SETICON,
324 (WPARAM)pInfo->hConn,
325 0);
326 }
327
328 FillServerAddressCombo(pInfo);
329 ReLoadGeneralPage(pInfo);
330 }
331
332
333 INT_PTR CALLBACK
GeneralDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)334 GeneralDlgProc(HWND hDlg,
335 UINT message,
336 WPARAM wParam,
337 LPARAM lParam)
338 {
339 PINFO pInfo = (PINFO)GetWindowLongPtrW(hDlg,
340 GWLP_USERDATA);
341
342 switch (message)
343 {
344 case WM_INITDIALOG:
345 GeneralOnInit(hDlg, (PINFO)lParam);
346 return TRUE;
347
348 case WM_COMMAND:
349 {
350 switch(LOWORD(wParam))
351 {
352 case IDC_SERVERCOMBO:
353 if (HIWORD(wParam) == CBN_SELCHANGE)
354 {
355 INT last, cur;
356
357 cur = SendDlgItemMessageW(hDlg,
358 IDC_SERVERCOMBO,
359 CB_GETCURSEL,
360 0,
361 0);
362
363 last = SendDlgItemMessageW(hDlg,
364 IDC_SERVERCOMBO,
365 CB_GETCOUNT,
366 0,
367 0);
368 if ((cur + 1) == last)
369 MessageBoxW(hDlg, L"SMB is not yet supported", L"RDP error", MB_ICONERROR);
370 else
371 {
372 LoadUsernameHint(hDlg, cur);
373 }
374 }
375 break;
376
377 case IDC_SAVE:
378 SaveAllSettings(pInfo);
379 SaveRdpSettingsToFile(NULL, pInfo->pRdpSettings);
380 break;
381
382 case IDC_SAVEAS:
383 DoSaveAs(pInfo);
384 break;
385
386 case IDC_OPEN:
387 DoOpenFile(pInfo);
388 break;
389 }
390
391 break;
392 }
393
394 case WM_CLOSE:
395 {
396 if (pInfo->hLogon)
397 DestroyIcon(pInfo->hLogon);
398
399 if (pInfo->hConn)
400 DestroyIcon(pInfo->hConn);
401
402 break;
403 }
404 }
405
406 return 0;
407 }
408
409
410 static PSETTINGS_ENTRY
GetPossibleSettings(IN LPCWSTR lpDeviceName,OUT DWORD * pSettingsCount,OUT PSETTINGS_ENTRY * CurrentSettings)411 GetPossibleSettings(IN LPCWSTR lpDeviceName,
412 OUT DWORD* pSettingsCount,
413 OUT PSETTINGS_ENTRY* CurrentSettings)
414 {
415 DEVMODEW devmode;
416 DWORD NbSettings = 0;
417 DWORD iMode = 0;
418 DWORD dwFlags = 0;
419 PSETTINGS_ENTRY Settings = NULL;
420 HDC hDC;
421 PSETTINGS_ENTRY Current;
422 DWORD bpp, xres, yres, checkbpp;
423
424 /* Get current settings */
425 *CurrentSettings = NULL;
426 hDC = CreateICW(NULL, lpDeviceName, NULL, NULL);
427 bpp = GetDeviceCaps(hDC, PLANES);
428 bpp *= GetDeviceCaps(hDC, BITSPIXEL);
429 xres = GetDeviceCaps(hDC, HORZRES);
430 yres = GetDeviceCaps(hDC, VERTRES);
431 DeleteDC(hDC);
432
433 /* List all settings */
434 devmode.dmSize = (WORD)sizeof(DEVMODE);
435 devmode.dmDriverExtra = 0;
436
437 if (!EnumDisplaySettingsExW(lpDeviceName, ENUM_CURRENT_SETTINGS, &devmode, dwFlags))
438 return NULL;
439
440 while (EnumDisplaySettingsExW(lpDeviceName, iMode, &devmode, dwFlags))
441 {
442 if (devmode.dmBitsPerPel==8 ||
443 devmode.dmBitsPerPel==16 ||
444 devmode.dmBitsPerPel==24 ||
445 devmode.dmBitsPerPel==32)
446 {
447 checkbpp=1;
448 }
449 else
450 checkbpp=0;
451
452 if (devmode.dmPelsWidth < 640 ||
453 devmode.dmPelsHeight < 480 || checkbpp == 0)
454 {
455 iMode++;
456 continue;
457 }
458
459 Current = HeapAlloc(GetProcessHeap(), 0, sizeof(SETTINGS_ENTRY));
460 if (Current != NULL)
461 {
462 /* Sort resolutions by increasing height, and BPP */
463 PSETTINGS_ENTRY Previous = NULL;
464 PSETTINGS_ENTRY Next = Settings;
465 Current->dmPelsWidth = devmode.dmPelsWidth;
466 Current->dmPelsHeight = devmode.dmPelsHeight;
467 Current->dmBitsPerPel = devmode.dmBitsPerPel;
468 while (Next != NULL &&
469 (Next->dmPelsWidth < Current->dmPelsWidth ||
470 (Next->dmPelsWidth == Current->dmPelsWidth && Next->dmPelsHeight < Current->dmPelsHeight) ||
471 (Next->dmPelsHeight == Current->dmPelsHeight &&
472 Next->dmPelsWidth == Current->dmPelsWidth &&
473 Next->dmBitsPerPel < Current->dmBitsPerPel )))
474 {
475 Previous = Next;
476 Next = Next->Flink;
477 }
478 Current->Blink = Previous;
479 Current->Flink = Next;
480 if (Previous == NULL)
481 Settings = Current;
482 else
483 Previous->Flink = Current;
484 if (Next != NULL)
485 Next->Blink = Current;
486 if (devmode.dmPelsWidth == xres && devmode.dmPelsHeight == yres && devmode.dmBitsPerPel == bpp)
487 {
488 *CurrentSettings = Current;
489 }
490 NbSettings++;
491 }
492 iMode++;
493 }
494
495 *pSettingsCount = NbSettings;
496 return Settings;
497 }
498
499
500 static BOOL
AddDisplayDevice(PINFO pInfo,PDISPLAY_DEVICEW DisplayDevice)501 AddDisplayDevice(PINFO pInfo, PDISPLAY_DEVICEW DisplayDevice)
502 {
503 PDISPLAY_DEVICE_ENTRY newEntry = NULL;
504 LPWSTR description = NULL;
505 LPWSTR name = NULL;
506 LPWSTR key = NULL;
507 LPWSTR devid = NULL;
508 SIZE_T descriptionSize, nameSize, keySize, devidSize;
509 PSETTINGS_ENTRY Current;
510 DWORD ResolutionsCount = 1;
511 DWORD i;
512
513 newEntry = HeapAlloc(GetProcessHeap(),
514 0,
515 sizeof(DISPLAY_DEVICE_ENTRY));
516 if (!newEntry) goto ByeBye;
517 ZeroMemory(newEntry, sizeof(DISPLAY_DEVICE_ENTRY));
518
519 newEntry->Settings = GetPossibleSettings(DisplayDevice->DeviceName,
520 &newEntry->SettingsCount,
521 &newEntry->CurrentSettings);
522 if (!newEntry->Settings) goto ByeBye;
523
524 newEntry->InitialSettings.dmPelsWidth = newEntry->CurrentSettings->dmPelsWidth;
525 newEntry->InitialSettings.dmPelsHeight = newEntry->CurrentSettings->dmPelsHeight;
526 newEntry->InitialSettings.dmBitsPerPel = newEntry->CurrentSettings->dmBitsPerPel;
527
528 /* Count different resolutions */
529 for (Current = newEntry->Settings; Current != NULL; Current = Current->Flink)
530 {
531 if (Current->Flink != NULL &&
532 ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) &&
533 (Current->dmPelsHeight != Current->Flink->dmPelsHeight)))
534 {
535 ResolutionsCount++;
536 }
537 }
538
539 newEntry->Resolutions = HeapAlloc(GetProcessHeap(),
540 0,
541 ResolutionsCount * (sizeof(RESOLUTION_INFO) + 1));
542 if (!newEntry->Resolutions) goto ByeBye;
543
544 newEntry->ResolutionsCount = ResolutionsCount;
545
546 /* Fill resolutions infos */
547 for (Current = newEntry->Settings, i = 0; Current != NULL; Current = Current->Flink)
548 {
549 if (Current->Flink == NULL ||
550 (Current->Flink != NULL &&
551 ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) &&
552 (Current->dmPelsHeight != Current->Flink->dmPelsHeight))))
553 {
554 newEntry->Resolutions[i].dmPelsWidth = Current->dmPelsWidth;
555 newEntry->Resolutions[i].dmPelsHeight = Current->dmPelsHeight;
556 i++;
557 }
558 }
559
560 /* fullscreen */
561 newEntry->Resolutions[i].dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
562 newEntry->Resolutions[i].dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
563
564 descriptionSize = (wcslen(DisplayDevice->DeviceString) + 1) * sizeof(WCHAR);
565 description = HeapAlloc(GetProcessHeap(), 0, descriptionSize);
566 if (!description) goto ByeBye;
567
568 nameSize = (wcslen(DisplayDevice->DeviceName) + 1) * sizeof(WCHAR);
569 name = HeapAlloc(GetProcessHeap(), 0, nameSize);
570 if (!name) goto ByeBye;
571
572 keySize = (wcslen(DisplayDevice->DeviceKey) + 1) * sizeof(WCHAR);
573 key = HeapAlloc(GetProcessHeap(), 0, keySize);
574 if (!key) goto ByeBye;
575
576 devidSize = (wcslen(DisplayDevice->DeviceID) + 1) * sizeof(WCHAR);
577 devid = HeapAlloc(GetProcessHeap(), 0, devidSize);
578 if (!devid) goto ByeBye;
579
580 memcpy(description, DisplayDevice->DeviceString, descriptionSize);
581 memcpy(name, DisplayDevice->DeviceName, nameSize);
582 memcpy(key, DisplayDevice->DeviceKey, keySize);
583 memcpy(devid, DisplayDevice->DeviceID, devidSize);
584 newEntry->DeviceDescription = description;
585 newEntry->DeviceName = name;
586 newEntry->DeviceKey = key;
587 newEntry->DeviceID = devid;
588 newEntry->DeviceStateFlags = DisplayDevice->StateFlags;
589 newEntry->Flink = pInfo->DisplayDeviceList;
590 pInfo->DisplayDeviceList = newEntry;
591 return TRUE;
592
593 ByeBye:
594 if (newEntry != NULL)
595 {
596 if (newEntry->Settings != NULL)
597 {
598 Current = newEntry->Settings;
599 while (Current != NULL)
600 {
601 PSETTINGS_ENTRY Next = Current->Flink;
602 HeapFree(GetProcessHeap(), 0, Current);
603 Current = Next;
604 }
605 }
606 if (newEntry->Resolutions != NULL)
607 HeapFree(GetProcessHeap(), 0, newEntry->Resolutions);
608 HeapFree(GetProcessHeap(), 0, newEntry);
609 }
610 if (description != NULL)
611 HeapFree(GetProcessHeap(), 0, description);
612 if (name != NULL)
613 HeapFree(GetProcessHeap(), 0, name);
614 if (key != NULL)
615 HeapFree(GetProcessHeap(), 0, key);
616 if (devid != NULL)
617 HeapFree(GetProcessHeap(), 0, devid);
618 return FALSE;
619 }
620
621
622 static VOID
OnResolutionChanged(PINFO pInfo,INT position)623 OnResolutionChanged(PINFO pInfo, INT position)
624 {
625 WCHAR Buffer[64];
626 INT MaxSlider;
627
628 MaxSlider = SendDlgItemMessageW(pInfo->hDisplayPage,
629 IDC_GEOSLIDER,
630 TBM_GETRANGEMAX,
631 0,
632 0);
633
634 if (position == MaxSlider)
635 {
636 LoadStringW(hInst,
637 IDS_FULLSCREEN,
638 Buffer,
639 sizeof(Buffer) / sizeof(WCHAR));
640 }
641 else
642 {
643 WCHAR Pixel[64];
644
645 if (LoadStringW(hInst,
646 IDS_PIXEL,
647 Pixel,
648 sizeof(Pixel) / sizeof(WCHAR)))
649 {
650 swprintf(Buffer,
651 Pixel,
652 pInfo->DisplayDeviceList->Resolutions[position].dmPelsWidth,
653 pInfo->DisplayDeviceList->Resolutions[position].dmPelsHeight,
654 Pixel);
655 }
656 }
657
658 SendDlgItemMessageW(pInfo->hDisplayPage,
659 IDC_SETTINGS_RESOLUTION_TEXT,
660 WM_SETTEXT,
661 0,
662 (LPARAM)Buffer);
663 }
664
665
666 static VOID
FillResolutionsAndColors(PINFO pInfo)667 FillResolutionsAndColors(PINFO pInfo)
668 {
669 PSETTINGS_ENTRY Current;
670 DWORD index, i, num;
671 DWORD MaxBpp = 0;
672 UINT types[5];
673
674 pInfo->CurrentDisplayDevice = pInfo->DisplayDeviceList; /* Update global variable */
675
676 /* find max bpp */
677 SendDlgItemMessageW(pInfo->hDisplayPage,
678 IDC_BPPCOMBO,
679 CB_RESETCONTENT,
680 0,
681 0);
682 for (Current = pInfo->DisplayDeviceList->Settings; Current != NULL; Current = Current->Flink)
683 {
684 if (Current->dmBitsPerPel > MaxBpp)
685 MaxBpp = Current->dmBitsPerPel;
686 }
687 switch (MaxBpp)
688 {
689 case 32: num = 4; break;
690 case 24: num = 3; break;
691 case 16: num = 2; break;
692 case 15: num = 1; break;
693 case 8: num = 0; break;
694 default: num = 0; break;
695 }
696
697 types[0] = IDS_256COLORS;
698 types[1] = IDS_HIGHCOLOR15;
699 types[2] = IDS_HIGHCOLOR16;
700 types[3] = IDS_HIGHCOLOR24;
701 types[4] = IDS_HIGHCOLOR32;
702
703 /* Fill color depths combo box */
704 SendDlgItemMessageW(pInfo->hDisplayPage,
705 IDC_BPPCOMBO,
706 CB_RESETCONTENT,
707 0,
708 0);
709
710 for (i = 0, Current = pInfo->DisplayDeviceList->Settings;
711 i <= num && Current != NULL;
712 i++, Current = Current->Flink)
713 {
714 WCHAR Buffer[64];
715 if (LoadStringW(hInst,
716 types[i],
717 Buffer,
718 sizeof(Buffer) / sizeof(WCHAR)))
719 {
720 index = (DWORD)SendDlgItemMessageW(pInfo->hDisplayPage,
721 IDC_BPPCOMBO,
722 CB_FINDSTRINGEXACT,
723 (WPARAM)-1,
724 (LPARAM)Buffer);
725 if (index == (DWORD)CB_ERR)
726 {
727 index = (DWORD)SendDlgItemMessageW(pInfo->hDisplayPage,
728 IDC_BPPCOMBO,
729 CB_ADDSTRING,
730 0,
731 (LPARAM)Buffer);
732 SendDlgItemMessageW(pInfo->hDisplayPage,
733 IDC_BPPCOMBO,
734 CB_SETITEMDATA,
735 index,
736 types[i]);
737 }
738 }
739 }
740
741 /* Fill resolutions slider */
742 SendDlgItemMessageW(pInfo->hDisplayPage,
743 IDC_GEOSLIDER,
744 TBM_CLEARTICS,
745 TRUE,
746 0);
747 SendDlgItemMessageW(pInfo->hDisplayPage,
748 IDC_GEOSLIDER,
749 TBM_SETRANGE,
750 TRUE,
751 MAKELONG(0, pInfo->DisplayDeviceList->ResolutionsCount)); //extra 1 for full screen
752
753
754 }
755
756
757 static VOID
ReLoadDisplayPage(PINFO pInfo)758 ReLoadDisplayPage(PINFO pInfo)
759 {
760 DWORD index;
761 INT width, height, pos = 0;
762 INT bpp, num, i, screenmode;
763 BOOL bSet = FALSE;
764
765 /* get fullscreen info */
766 screenmode = GetIntegerFromSettings(pInfo->pRdpSettings, L"screen mode id");
767
768 /* set trackbar position */
769 width = GetIntegerFromSettings(pInfo->pRdpSettings, L"desktopwidth");
770 height = GetIntegerFromSettings(pInfo->pRdpSettings, L"desktopheight");
771
772 if (width != -1 && height != -1)
773 {
774 if(screenmode == 2)
775 {
776 pos = SendDlgItemMessageW(pInfo->hDisplayPage,
777 IDC_GEOSLIDER,
778 TBM_GETRANGEMAX,
779 0,
780 0);
781 }
782 else
783 {
784 for (index = 0; index < pInfo->CurrentDisplayDevice->ResolutionsCount; index++)
785 {
786 if (pInfo->CurrentDisplayDevice->Resolutions[index].dmPelsWidth == width &&
787 pInfo->CurrentDisplayDevice->Resolutions[index].dmPelsHeight == height)
788 {
789 pos = index;
790 break;
791 }
792 }
793 }
794 }
795
796 /* set slider position */
797 SendDlgItemMessageW(pInfo->hDisplayPage,
798 IDC_GEOSLIDER,
799 TBM_SETPOS,
800 TRUE,
801 pos);
802
803 OnResolutionChanged(pInfo, pos);
804
805
806 /* set color combo */
807 bpp = GetIntegerFromSettings(pInfo->pRdpSettings, L"session bpp");
808
809 num = SendDlgItemMessageW(pInfo->hDisplayPage,
810 IDC_BPPCOMBO,
811 CB_GETCOUNT,
812 0,
813 0);
814 for (i = 0; i < num; i++)
815 {
816 INT data = SendDlgItemMessageW(pInfo->hDisplayPage,
817 IDC_BPPCOMBO,
818 CB_GETITEMDATA,
819 i,
820 0);
821 if (data == bpp)
822 {
823 SendDlgItemMessageW(pInfo->hDisplayPage,
824 IDC_BPPCOMBO,
825 CB_SETCURSEL,
826 i,
827 0);
828 bSet = TRUE;
829 break;
830 }
831 }
832
833 if (!bSet)
834 {
835 SendDlgItemMessageW(pInfo->hDisplayPage,
836 IDC_BPPCOMBO,
837 CB_SETCURSEL,
838 num - 1,
839 0);
840 }
841 }
842
843
844 static VOID
DisplayOnInit(HWND hwnd,PINFO pInfo)845 DisplayOnInit(HWND hwnd,
846 PINFO pInfo)
847 {
848 DISPLAY_DEVICEW displayDevice;
849 DWORD iDevNum = 0;
850 BOOL GotDev = FALSE;
851
852 SetWindowLongPtrW(hwnd,
853 GWLP_USERDATA,
854 (LONG_PTR)pInfo);
855
856 pInfo->hDisplayPage = hwnd;
857
858 SetWindowPos(pInfo->hDisplayPage,
859 NULL,
860 2,
861 22,
862 0,
863 0,
864 SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
865
866 pInfo->hRemote = LoadImageW(hInst,
867 MAKEINTRESOURCEW(IDI_REMOTE),
868 IMAGE_ICON,
869 32,
870 32,
871 LR_DEFAULTCOLOR);
872 if (pInfo->hRemote)
873 {
874 SendDlgItemMessageW(pInfo->hDisplayPage,
875 IDC_REMICON,
876 STM_SETICON,
877 (WPARAM)pInfo->hRemote,
878 0);
879 }
880
881 pInfo->hColor = LoadImageW(hInst,
882 MAKEINTRESOURCEW(IDI_COLORS),
883 IMAGE_ICON,
884 32,
885 32,
886 LR_DEFAULTCOLOR);
887 if (pInfo->hColor)
888 {
889 SendDlgItemMessageW(pInfo->hDisplayPage,
890 IDC_COLORSICON,
891 STM_SETICON,
892 (WPARAM)pInfo->hColor,
893 0);
894 }
895
896 pInfo->hSpectrum = LoadImageW(hInst,
897 MAKEINTRESOURCEW(IDB_SPECT),
898 IMAGE_BITMAP,
899 0,
900 0,
901 LR_DEFAULTCOLOR);
902 if (pInfo->hSpectrum)
903 {
904 GetObjectW(pInfo->hSpectrum,
905 sizeof(BITMAP),
906 &pInfo->bitmap);
907 }
908
909 /* Get video cards list */
910 displayDevice.cb = (DWORD)sizeof(DISPLAY_DEVICE);
911 while (EnumDisplayDevicesW(NULL, iDevNum, &displayDevice, 0x1))
912 {
913 if ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0)
914 {
915 if (AddDisplayDevice(pInfo, &displayDevice))
916 GotDev = TRUE;
917 }
918 iDevNum++;
919 }
920
921 if (GotDev)
922 {
923 FillResolutionsAndColors(pInfo);
924 ReLoadDisplayPage(pInfo);
925 }
926 }
927
928
929 INT_PTR CALLBACK
DisplayDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)930 DisplayDlgProc(HWND hDlg,
931 UINT message,
932 WPARAM wParam,
933 LPARAM lParam)
934 {
935 PINFO pInfo = (PINFO)GetWindowLongPtrW(hDlg,
936 GWLP_USERDATA);
937
938 switch (message)
939 {
940 case WM_INITDIALOG:
941 DisplayOnInit(hDlg, (PINFO)lParam);
942 return TRUE;
943
944 case WM_DRAWITEM:
945 {
946 LPDRAWITEMSTRUCT lpDrawItem;
947 lpDrawItem = (LPDRAWITEMSTRUCT)lParam;
948 if(lpDrawItem->CtlID == IDC_COLORIMAGE)
949 {
950 HDC hdcMem;
951 HBITMAP hSpecOld;
952 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
953 if (hdcMem != NULL)
954 {
955 hSpecOld = SelectObject(hdcMem, pInfo->hSpectrum);
956 StretchBlt(lpDrawItem->hDC,
957 lpDrawItem->rcItem.left,
958 lpDrawItem->rcItem.top,
959 lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
960 lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
961 hdcMem,
962 0,
963 0,
964 pInfo->bitmap.bmWidth,
965 pInfo->bitmap.bmHeight,
966 SRCCOPY);
967 SelectObject(hdcMem, hSpecOld);
968 DeleteDC(hdcMem);
969 }
970 }
971 break;
972 }
973
974 case WM_HSCROLL:
975 {
976 switch (LOWORD(wParam))
977 {
978 case TB_LINEUP:
979 case TB_LINEDOWN:
980 case TB_PAGEUP:
981 case TB_PAGEDOWN:
982 case TB_TOP:
983 case TB_BOTTOM:
984 case TB_ENDTRACK:
985 {
986 INT newPosition = (DWORD)SendDlgItemMessageW(hDlg, IDC_GEOSLIDER, TBM_GETPOS, 0, 0);
987 OnResolutionChanged(pInfo, newPosition);
988 break;
989 }
990
991 case TB_THUMBTRACK:
992 OnResolutionChanged(pInfo, HIWORD(wParam));
993 break;
994 }
995 break;
996 }
997
998 case WM_CLOSE:
999 {
1000 if (pInfo->hRemote)
1001 DestroyIcon(pInfo->hRemote);
1002
1003 if (pInfo->hColor)
1004 DestroyIcon(pInfo->hColor);
1005
1006 if (pInfo->hSpectrum)
1007 DeleteObject(pInfo->hSpectrum);
1008
1009 break;
1010 }
1011
1012 break;
1013 }
1014 return 0;
1015 }
1016
1017
1018 static BOOL
OnMainCreate(HWND hwnd,PRDPSETTINGS pRdpSettings)1019 OnMainCreate(HWND hwnd,
1020 PRDPSETTINGS pRdpSettings)
1021 {
1022 PINFO pInfo;
1023 TCITEMW item;
1024 BOOL bRet = FALSE;
1025
1026 pInfo = HeapAlloc(GetProcessHeap(),
1027 HEAP_ZERO_MEMORY,
1028 sizeof(INFO));
1029 if (pInfo)
1030 {
1031 SetWindowLongPtrW(hwnd,
1032 GWLP_USERDATA,
1033 (LONG_PTR)pInfo);
1034
1035 pInfo->hSelf = hwnd;
1036
1037 /* add main settings pointer */
1038 pInfo->pRdpSettings = pRdpSettings;
1039
1040 /* set the dialog icons */
1041 pInfo->hMstscSm = LoadImageW(hInst,
1042 MAKEINTRESOURCEW(IDI_MSTSC),
1043 IMAGE_ICON,
1044 16,
1045 16,
1046 LR_DEFAULTCOLOR);
1047 if (pInfo->hMstscSm)
1048 {
1049 SendMessageW(hwnd,
1050 WM_SETICON,
1051 ICON_SMALL,
1052 (WPARAM)pInfo->hMstscSm);
1053 }
1054 pInfo->hMstscLg = LoadImageW(hInst,
1055 MAKEINTRESOURCEW(IDI_MSTSC),
1056 IMAGE_ICON,
1057 32,
1058 32,
1059 LR_DEFAULTCOLOR);
1060 if (pInfo->hMstscLg)
1061 {
1062 SendMessageW(hwnd,
1063 WM_SETICON,
1064 ICON_BIG,
1065 (WPARAM)pInfo->hMstscLg);
1066 }
1067
1068 pInfo->hHeader = (HBITMAP)LoadImageW(hInst,
1069 MAKEINTRESOURCEW(IDB_HEADER),
1070 IMAGE_BITMAP,
1071 0,
1072 0,
1073 LR_DEFAULTCOLOR);
1074 if (pInfo->hHeader)
1075 {
1076 GetObjectW(pInfo->hHeader,
1077 sizeof(BITMAP),
1078 &pInfo->headerbitmap);
1079 }
1080
1081 /* setup the tabs */
1082 pInfo->hTab = GetDlgItem(hwnd, IDC_TAB);
1083 if (pInfo->hTab)
1084 {
1085 if (CreateDialogParamW(hInst,
1086 MAKEINTRESOURCEW(IDD_GENERAL),
1087 pInfo->hTab,
1088 GeneralDlgProc,
1089 (LPARAM)pInfo))
1090 {
1091 WCHAR str[256];
1092 ZeroMemory(&item, sizeof(TCITEM));
1093 item.mask = TCIF_TEXT;
1094 if (LoadStringW(hInst, IDS_TAB_GENERAL, str, 256))
1095 item.pszText = str;
1096 item.cchTextMax = 256;
1097 (void)TabCtrl_InsertItem(pInfo->hTab, 0, &item);
1098 }
1099
1100 if (CreateDialogParamW(hInst,
1101 MAKEINTRESOURCEW(IDD_DISPLAY),
1102 pInfo->hTab,
1103 DisplayDlgProc,
1104 (LPARAM)pInfo))
1105 {
1106 WCHAR str[256];
1107 ZeroMemory(&item, sizeof(TCITEM));
1108 item.mask = TCIF_TEXT;
1109 if (LoadStringW(hInst, IDS_TAB_DISPLAY, str, 256))
1110 item.pszText = str;
1111 item.cchTextMax = 256;
1112 (void)TabCtrl_InsertItem(pInfo->hTab, 1, &item);
1113 }
1114
1115 OnTabWndSelChange(pInfo);
1116 }
1117 }
1118
1119 return bRet;
1120 }
1121
Cleanup(PINFO pInfo)1122 static void Cleanup(PINFO pInfo)
1123 {
1124 if (pInfo)
1125 {
1126 if (pInfo->hMstscSm)
1127 DestroyIcon(pInfo->hMstscSm);
1128 if (pInfo->hMstscLg)
1129 DestroyIcon(pInfo->hMstscLg);
1130 if (pInfo->hHeader)
1131 DeleteObject(pInfo->hHeader);
1132 if (pInfo->hSpectrum)
1133 DeleteObject(pInfo->hSpectrum);
1134 if (pInfo->hRemote)
1135 DestroyIcon(pInfo->hRemote);
1136 if (pInfo->hLogon)
1137 DestroyIcon(pInfo->hLogon);
1138 if (pInfo->hConn)
1139 DestroyIcon(pInfo->hConn);
1140 if (pInfo->hColor)
1141 DestroyIcon(pInfo->hColor);
1142 HeapFree(GetProcessHeap(),
1143 0,
1144 pInfo);
1145 }
1146 }
1147
1148 static INT_PTR CALLBACK
DlgProc(HWND hDlg,UINT Message,WPARAM wParam,LPARAM lParam)1149 DlgProc(HWND hDlg,
1150 UINT Message,
1151 WPARAM wParam,
1152 LPARAM lParam)
1153 {
1154 PINFO pInfo;
1155
1156 /* Get the window context */
1157 pInfo = (PINFO)GetWindowLongPtrW(hDlg,
1158 GWLP_USERDATA);
1159 if (pInfo == NULL && Message != WM_INITDIALOG)
1160 {
1161 goto HandleDefaultMessage;
1162 }
1163
1164 switch(Message)
1165 {
1166 case WM_INITDIALOG:
1167 OnMainCreate(hDlg, (PRDPSETTINGS)lParam);
1168 break;
1169
1170 case WM_COMMAND:
1171 {
1172 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
1173 {
1174 if (LOWORD(wParam) == IDOK )
1175 {
1176 SaveAllSettings(pInfo);
1177 SaveRdpSettingsToFile(NULL, pInfo->pRdpSettings);
1178 }
1179 Cleanup(pInfo);
1180 EndDialog(hDlg, LOWORD(wParam));
1181 }
1182
1183 break;
1184 }
1185
1186 case WM_NOTIFY:
1187 {
1188 //INT idctrl;
1189 LPNMHDR pnmh;
1190 //idctrl = (int)wParam;
1191 pnmh = (LPNMHDR)lParam;
1192 if (//(pnmh->hwndFrom == pInfo->hSelf) &&
1193 (pnmh->idFrom == IDC_TAB) &&
1194 (pnmh->code == TCN_SELCHANGE))
1195 {
1196 OnTabWndSelChange(pInfo);
1197 }
1198
1199 break;
1200 }
1201
1202 case WM_PAINT:
1203 {
1204 PAINTSTRUCT ps;
1205 HDC hdc;
1206
1207 hdc = BeginPaint(hDlg, &ps);
1208 if (hdc != NULL)
1209 {
1210 HDC hdcMem = CreateCompatibleDC(hdc);
1211 if (hdcMem)
1212 {
1213 WCHAR szBuffer[32];
1214 RECT bmpRc, txtRc;
1215 LOGFONTW lf;
1216 HFONT hFont, hFontOld;
1217 HBITMAP hBmpOld;
1218
1219 GetClientRect(pInfo->hSelf, &bmpRc);
1220
1221 hBmpOld = SelectObject(hdcMem, pInfo->hHeader);
1222 StretchBlt(hdc,
1223 0,
1224 0,
1225 bmpRc.right,
1226 pInfo->headerbitmap.bmHeight,
1227 hdcMem,
1228 0,
1229 0,
1230 pInfo->headerbitmap.bmWidth,
1231 pInfo->headerbitmap.bmHeight,
1232 SRCCOPY);
1233
1234 SelectObject(hdcMem, hBmpOld);
1235 txtRc.left = bmpRc.right / 4;
1236 txtRc.top = 10;
1237 txtRc.right = bmpRc.right * 3 / 4;
1238 txtRc.bottom = pInfo->headerbitmap.bmHeight / 2;
1239
1240 ZeroMemory(&lf, sizeof(LOGFONTW));
1241
1242 if (LoadStringW(hInst,
1243 IDS_HEADERTEXT1,
1244 szBuffer,
1245 sizeof(szBuffer) / sizeof(WCHAR)))
1246 {
1247 lf.lfHeight = 20;
1248 lf.lfCharSet = OEM_CHARSET;
1249 lf.lfQuality = DEFAULT_QUALITY;
1250 lf.lfWeight = FW_MEDIUM;
1251 wcscpy(lf.lfFaceName, L"Tahoma");
1252
1253 hFont = CreateFontIndirectW(&lf);
1254 if (hFont)
1255 {
1256 hFontOld = SelectObject(hdc, hFont);
1257
1258 DPtoLP(hdc, (PPOINT)&txtRc, 2);
1259 SetTextColor(hdc, RGB(255,255,255));
1260 SetBkMode(hdc, TRANSPARENT);
1261 DrawTextW(hdc,
1262 szBuffer,
1263 -1,
1264 &txtRc,
1265 DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP | DT_CENTER); //DT_CENTER makes the text visible in RTL layouts...
1266 SelectObject(hdc, hFontOld);
1267 DeleteObject(hFont);
1268 }
1269 }
1270
1271 txtRc.left = bmpRc.right / 4;
1272 txtRc.top = txtRc.bottom - 5;
1273 #ifdef __REACTOS__
1274 txtRc.right = bmpRc.right * 4 / 5;
1275 #else
1276 txtRc.right = bmpRc.right * 3 / 4;
1277 #endif
1278 txtRc.bottom = pInfo->headerbitmap.bmHeight * 9 / 10;
1279
1280 if (LoadStringW(hInst,
1281 IDS_HEADERTEXT2,
1282 szBuffer,
1283 sizeof(szBuffer) / sizeof(WCHAR)))
1284 {
1285 lf.lfHeight = 24;
1286 lf.lfCharSet = OEM_CHARSET;
1287 lf.lfQuality = DEFAULT_QUALITY;
1288 lf.lfWeight = FW_EXTRABOLD;
1289 wcscpy(lf.lfFaceName, L"Tahoma");
1290
1291 hFont = CreateFontIndirectW(&lf);
1292 if (hFont)
1293 {
1294 hFontOld = SelectObject(hdc, hFont);
1295
1296 DPtoLP(hdc, (PPOINT)&txtRc, 2);
1297 SetTextColor(hdc, RGB(255,255,255));
1298 SetBkMode(hdc, TRANSPARENT);
1299 DrawTextW(hdc,
1300 szBuffer,
1301 -1,
1302 &txtRc,
1303 DT_TOP | DT_SINGLELINE);
1304 SelectObject(hdc, hFontOld);
1305 DeleteObject(hFont);
1306 }
1307 }
1308
1309 DeleteDC(hdcMem);
1310 }
1311
1312 EndPaint(hDlg, &ps);
1313 }
1314
1315 break;
1316 }
1317
1318 case WM_CLOSE:
1319 {
1320 Cleanup(pInfo);
1321 EndDialog(hDlg, 0);
1322 }
1323 break;
1324
1325 HandleDefaultMessage:
1326 default:
1327 return FALSE;
1328 }
1329
1330 return FALSE;
1331 }
1332
1333
1334 BOOL
OpenRDPConnectDialog(HINSTANCE hInstance,PRDPSETTINGS pRdpSettings)1335 OpenRDPConnectDialog(HINSTANCE hInstance,
1336 PRDPSETTINGS pRdpSettings)
1337 {
1338 INITCOMMONCONTROLSEX iccx;
1339
1340 hInst = hInstance;
1341
1342 iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
1343 iccx.dwICC = ICC_TAB_CLASSES;
1344 InitCommonControlsEx(&iccx);
1345
1346 return (DialogBoxParamW(hInst,
1347 MAKEINTRESOURCEW(IDD_CONNECTDIALOG),
1348 NULL,
1349 DlgProc,
1350 (LPARAM)pRdpSettings) == IDOK);
1351 }
1352