bd956cdb6d2c70c327e358f828594b9f40c690e5
[reactos.git] / reactos / dll / cpl / intl / advanced.c
1 #include "intl.h"
2
3 typedef struct CPStruct
4 {
5 WORD Status;
6 UINT CPage;
7 HANDLE hCPage;
8 TCHAR Name[MAX_PATH];
9 struct CPStruct *NextItem;
10 } CPAGE, *LPCPAGE;
11
12 static LPCPAGE PCPage = NULL;
13 static HINF hIntlInf;
14 static BOOL bSpain = FALSE;
15 static HWND hLangList;
16
17 static BOOL
18 GetSupportedCP(VOID)
19 {
20 UINT uiCPage, Number;
21 LONG Count;
22 INFCONTEXT infCont;
23 LPCPAGE lpCPage;
24 HANDLE hCPage;
25 CPINFOEX cpInfEx;
26 //TCHAR Section[MAX_PATH];
27
28 Count = SetupGetLineCountW(hIntlInf, L"CodePages");
29 if (Count <= 0) return FALSE;
30
31 for (Number = 0; Number < (UINT)Count; Number++)
32 {
33 if (SetupGetLineByIndexW(hIntlInf, L"CodePages", Number, &infCont) &&
34 SetupGetIntField(&infCont, 0, (PINT)&uiCPage))
35 {
36 if (!(hCPage = GlobalAlloc(GHND, sizeof(CPAGE)))) return FALSE;
37
38 lpCPage = GlobalLock(hCPage);
39 lpCPage->CPage = uiCPage;
40 lpCPage->hCPage = hCPage;
41 lpCPage->Status = 0;
42 (lpCPage->Name)[0] = 0;
43
44 if (GetCPInfoEx(uiCPage, 0, &cpInfEx))
45 {
46 wcscpy(lpCPage->Name, cpInfEx.CodePageName);
47 }
48 else if (!SetupGetStringFieldW(&infCont, 1, lpCPage->Name, MAX_PATH, NULL))
49 {
50 GlobalUnlock(hCPage);
51 GlobalFree(hCPage);
52 continue;
53 }
54
55 lpCPage->NextItem = PCPage;
56 PCPage = lpCPage;
57 }
58 }
59
60 return TRUE;
61 }
62
63 static BOOL CALLBACK
64 InstalledCPProc(PWSTR lpStr)
65 {
66 LPCPAGE lpCP;
67 UINT uiCP;
68
69 lpCP = PCPage;
70 uiCP = _wtol(lpStr);
71
72 for (;;)
73 {
74 if (!lpCP) break;
75 if (lpCP->CPage == uiCP)
76 {
77 lpCP->Status |= 0x0001;
78 break;
79 }
80 lpCP = lpCP->NextItem;
81 }
82
83 return TRUE;
84 }
85
86 static VOID
87 InitCodePagesList(HWND hwndDlg)
88 {
89 LPCPAGE lpCPage;
90 INT ItemIndex;
91 HWND hList;
92 LV_COLUMN column;
93 LV_ITEM item;
94 RECT ListRect;
95
96 hList = GetDlgItem(hwndDlg, IDC_CONV_TABLES);
97
98 hIntlInf = SetupOpenInfFileW(L"intl.inf", NULL, INF_STYLE_WIN4, NULL);
99
100 if (hIntlInf == INVALID_HANDLE_VALUE)
101 return;
102
103 if (!SetupOpenAppendInfFile(NULL, hIntlInf, NULL))
104 {
105 SetupCloseInfFile(hIntlInf);
106 hIntlInf = NULL;
107 return;
108 }
109
110 if (!GetSupportedCP())
111 return;
112
113 SetupCloseInfFile(hIntlInf);
114
115 if (!EnumSystemCodePages(InstalledCPProc, CP_INSTALLED))
116 return;
117
118 ZeroMemory(&column, sizeof(LV_COLUMN));
119 column.mask = LVCF_FMT|LVCF_TEXT|LVCF_WIDTH;
120 column.fmt = LVCFMT_LEFT;
121 GetClientRect(hList, &ListRect);
122 column.cx = ListRect.right - GetSystemMetrics(SM_CYHSCROLL);
123 (VOID) ListView_InsertColumn(hList, 0, &column);
124
125 (VOID) ListView_SetExtendedListViewStyle(hList, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT);
126
127 lpCPage = PCPage;
128
129 for (;;)
130 {
131 if (!lpCPage) break;
132 ZeroMemory(&item, sizeof(LV_ITEM));
133 item.mask = LVIF_TEXT|LVIF_PARAM|LVIF_STATE;
134 item.state = 0;
135 item.stateMask = LVIS_STATEIMAGEMASK;
136 item.pszText = lpCPage->Name;
137 item.lParam = (LPARAM)lpCPage;
138
139 ItemIndex = ListView_InsertItem(hList, &item);
140
141 if (ItemIndex >= 0)
142 {
143 if (lpCPage->Status & 0x0001)
144 {
145 ListView_SetItemState(hList, ItemIndex,
146 INDEXTOSTATEIMAGEMASK(LVIS_SELECTED),
147 LVIS_STATEIMAGEMASK);
148 }
149 else
150 {
151 ListView_SetItemState(hList, ItemIndex,
152 INDEXTOSTATEIMAGEMASK(LVIS_FOCUSED),
153 LVIS_STATEIMAGEMASK);
154 }
155 }
156
157 lpCPage = lpCPage->NextItem;
158 }
159 }
160
161 static BOOL CALLBACK
162 LocalesEnumProc(PWSTR lpLocale)
163 {
164 LCID lcid;
165 WCHAR lang[255];
166 INT index;
167 BOOL bNoShow = FALSE;
168
169 lcid = wcstoul(lpLocale, NULL, 16);
170
171 if (lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT) ||
172 lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT))
173 {
174 if (bSpain == FALSE)
175 {
176 LoadStringW(hApplet, IDS_SPAIN, lang, 255);
177 bSpain = TRUE;
178 }
179 else
180 {
181 bNoShow = TRUE;
182 }
183 }
184 else
185 {
186 GetLocaleInfoW(lcid, LOCALE_SLANGUAGE, lang, sizeof(lang)/sizeof(WCHAR));
187 }
188
189 if (bNoShow == FALSE)
190 {
191 index = SendMessageW(hLangList,
192 CB_ADDSTRING,
193 0,
194 (LPARAM)lang);
195
196 SendMessageW(hLangList,
197 CB_SETITEMDATA,
198 index,
199 (LPARAM)lcid);
200 }
201
202 return TRUE;
203 }
204
205 static VOID
206 InitLanguagesList(
207 HWND hwndDlg,
208 PGLOBALDATA pGlobalData)
209 {
210 WCHAR langSel[255];
211
212 hLangList = GetDlgItem(hwndDlg, IDC_LANGUAGE_COMBO);
213
214 bSpain = FALSE;
215 EnumSystemLocalesW(LocalesEnumProc, LCID_SUPPORTED);
216
217 /* Select current locale */
218 GetLocaleInfoW(pGlobalData->SystemLCID, LOCALE_SLANGUAGE, langSel, sizeof(langSel)/sizeof(WCHAR));
219
220 SendMessageW(hLangList, CB_SELECTSTRING, -1, (LPARAM)langSel);
221 }
222
223 static VOID
224 GetCurrentDPI(LPTSTR szDPI)
225 {
226 DWORD dwType, dwSize, dwDPI, dwDefDPI = 0x00000060; // Default 96 DPI
227 HKEY hKey;
228
229 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontDPI", 0, NULL,
230 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS)
231 {
232 wcscpy(szDPI, L"96");
233 return;
234 }
235
236 dwType = REG_DWORD;
237 dwSize = sizeof(DWORD);
238
239 if (RegQueryValueExW(hKey, L"LogPixels", NULL, &dwType, (LPBYTE)&dwDPI, &dwSize) != ERROR_SUCCESS)
240 {
241 if (RegSetValueExW(hKey, L"LogPixels", 0, REG_DWORD, (LPBYTE)&dwDefDPI, sizeof(DWORD)) == ERROR_SUCCESS)
242 {
243 wcscpy(szDPI, L"96");
244 RegCloseKey(hKey);
245 return;
246 }
247 }
248 else wsprintf(szDPI, L"%d", dwDPI);
249
250 RegCloseKey(hKey);
251 }
252
253 static
254 VOID
255 SaveFontSubstitutionSettings(
256 HWND hwnd,
257 PGLOBALDATA pGlobalData)
258 {
259 WCHAR szDefCP[5 + 1], szSection[MAX_PATH], szDPI[3 + 1];
260 HINF hFontInf;
261 UINT Count;
262
263 GetLocaleInfoW(MAKELCID(pGlobalData->SystemLCID, SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, szDefCP, sizeof(szDefCP) / sizeof(WCHAR));
264 GetCurrentDPI(szDPI);
265
266 wsprintf(szSection, L"Font.CP%s.%s", szDefCP, szDPI);
267
268 hFontInf = SetupOpenInfFileW(L"font.inf", NULL, INF_STYLE_WIN4, NULL);
269
270 if (hFontInf == INVALID_HANDLE_VALUE)
271 return;
272
273 if (!SetupOpenAppendInfFile(NULL, hFontInf, NULL))
274 {
275 SetupCloseInfFile(hFontInf);
276 return;
277 }
278
279 Count = (UINT) SetupGetLineCount(hFontInf, szSection);
280 if (Count <= 0) return;
281
282 if (!SetupInstallFromInfSectionW(hwnd, hFontInf, szSection, SPINST_REGISTRY & ~SPINST_FILES,
283 NULL, NULL, 0, NULL, NULL, NULL, NULL))
284 MessageBoxW(hwnd, L"Unable to install a new language for programs don't support unicode!",
285 NULL, MB_ICONERROR | MB_OK);
286
287 SetupCloseInfFile(hFontInf);
288 }
289
290
291 static
292 VOID
293 SaveFontLinkingSettings(
294 HWND hwnd,
295 PGLOBALDATA pGlobalData)
296 {
297 /* TODO */
298 }
299
300
301 static
302 VOID
303 SaveSystemSettings(
304 PGLOBALDATA pGlobalData)
305 {
306 WCHAR ACPPage[9];
307 WCHAR OEMPage[9];
308 HKEY langKey;
309 DWORD ret;
310 WCHAR value[5];
311 DWORD valuesize;
312
313 ret = GetLocaleInfoW(MAKELCID(pGlobalData->SystemLCID, SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, OEMPage, sizeof(OEMPage)/sizeof(WCHAR));
314 if (ret == 0)
315 {
316 PrintErrorMsgBox(IDS_ERROR_OEM_CODE_PAGE);
317 return;
318 }
319
320 ret = GetLocaleInfoW(MAKELCID(pGlobalData->SystemLCID, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, ACPPage, sizeof(ACPPage)/sizeof(WCHAR));
321 if (ret == 0)
322 {
323 PrintErrorMsgBox(IDS_ERROR_ANSI_CODE_PAGE);
324 return;
325 }
326
327 /* Set codepages */
328 ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage", &langKey);
329 if (ret != ERROR_SUCCESS)
330 {
331 PrintErrorMsgBox(IDS_ERROR_NLS_CODE_REG);
332 return;
333 }
334
335 RegSetValueExW(langKey, L"OEMCP", 0, REG_SZ, (BYTE *)OEMPage, (wcslen(OEMPage) +1 ) * sizeof(WCHAR));
336 RegSetValueExW(langKey, L"ACP", 0, REG_SZ, (BYTE *)ACPPage, (wcslen(ACPPage) +1 ) * sizeof(WCHAR));
337
338 RegCloseKey(langKey);
339
340
341 wsprintf(value, L"%04hX", LANGIDFROMLCID(pGlobalData->SystemLCID));
342 valuesize = (wcslen(value) + 1) * sizeof(WCHAR);
343
344 /* Set language */
345 ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language", &langKey);
346 if (ret != ERROR_SUCCESS)
347 {
348 PrintErrorMsgBox(IDS_ERROR_NLS_KEY_REG);
349 return;
350 }
351
352 RegSetValueExW(langKey, L"Default", 0, REG_SZ, (BYTE *)value, valuesize);
353 RegCloseKey(langKey);
354 }
355
356
357 /* Property page dialog callback */
358 INT_PTR CALLBACK
359 AdvancedPageProc(HWND hwndDlg,
360 UINT uMsg,
361 WPARAM wParam,
362 LPARAM lParam)
363 {
364 PGLOBALDATA pGlobalData;
365
366 pGlobalData = (PGLOBALDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
367
368 switch (uMsg)
369 {
370 case WM_INITDIALOG:
371 pGlobalData = (PGLOBALDATA)((LPPROPSHEETPAGE)lParam)->lParam;
372 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
373
374 InitLanguagesList(hwndDlg, pGlobalData);
375 InitCodePagesList(hwndDlg);
376 break;
377
378 case WM_COMMAND:
379 switch (LOWORD(wParam))
380 {
381 case IDC_LANGUAGE_COMBO:
382 if (HIWORD(wParam) == CBN_SELCHANGE)
383 {
384 LCID lcid;
385 INT iIndex;
386
387 iIndex = SendMessage(hLangList, CB_GETCURSEL, 0, 0);
388 if (iIndex == CB_ERR)
389 break;
390
391 lcid = SendMessage(hLangList, CB_GETITEMDATA, iIndex, 0);
392 if (lcid == (LCID)CB_ERR)
393 break;
394
395 pGlobalData->SystemLCID = lcid;
396
397 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
398 }
399 break;
400
401 case IDC_APPLY_CUR_USER_DEF_PROFILE:
402 if (HIWORD(wParam) == BN_CLICKED)
403 {
404 if (SendDlgItemMessageW(hwndDlg, IDC_APPLY_CUR_USER_DEF_PROFILE, BM_GETCHECK, 0, 0))
405 {
406 ResourceMessageBox(hwndDlg,
407 MB_OK | MB_ICONWARNING,
408 IDS_APPLY_DEFAULT_TITLE,
409 IDS_APPLY_DEFAULT_TEXT);
410 pGlobalData->bApplyToDefaultUser = TRUE;
411 }
412 else
413 {
414 pGlobalData->bApplyToDefaultUser = FALSE;
415 }
416
417 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
418 }
419 break;
420 }
421 break;
422
423 case WM_NOTIFY:
424 {
425 LPNMHDR lpnm = (LPNMHDR)lParam;
426
427 if (lpnm->code == (UINT)PSN_APPLY)
428 {
429 PropSheet_UnChanged(GetParent(hwndDlg), hwndDlg);
430
431 SaveSystemSettings(pGlobalData);
432 SaveFontSubstitutionSettings(hwndDlg, pGlobalData);
433 SaveFontLinkingSettings(hwndDlg, pGlobalData);
434 }
435 }
436 break;
437 }
438
439 return FALSE;
440 }
441
442 /* EOF */