Sync with trunk head (part 1 of 2)
[reactos.git] / dll / cpl / intl / advanced.c
1 #include <windows.h>
2 #include <commctrl.h>
3 #include <setupapi.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <tchar.h>
7 #include <cpl.h>
8
9 #include "intl.h"
10 #include "resource.h"
11
12 typedef struct CPStruct
13 {
14 WORD Status;
15 UINT CPage;
16 HANDLE hCPage;
17 TCHAR Name[MAX_PATH];
18 struct CPStruct *NextItem;
19 } CPAGE, *LPCPAGE;
20
21 static LPCPAGE PCPage = NULL;
22 static HINF hIntlInf;
23 static BOOL bSpain = FALSE;
24 static HWND hLangList;
25
26 static BOOL
27 GetSupportedCP(VOID)
28 {
29 UINT uiCPage, Number;
30 LONG Count;
31 INFCONTEXT infCont;
32 LPCPAGE lpCPage;
33 HANDLE hCPage;
34 CPINFOEX cpInfEx;
35 //TCHAR Section[MAX_PATH];
36
37 Count = SetupGetLineCount(hIntlInf, _T("CodePages"));
38 if (Count <= 0) return FALSE;
39
40 for (Number = 0; Number < (UINT)Count; Number++)
41 {
42 if (SetupGetLineByIndex(hIntlInf, _T("CodePages"), Number, &infCont) &&
43 SetupGetIntField(&infCont, 0, (PINT)&uiCPage))
44 {
45 if (!(hCPage = GlobalAlloc(GHND, sizeof(CPAGE)))) return FALSE;
46
47 lpCPage = GlobalLock(hCPage);
48 lpCPage->CPage = uiCPage;
49 lpCPage->hCPage = hCPage;
50 lpCPage->Status = 0;
51 (lpCPage->Name)[0] = 0;
52
53 if (GetCPInfoEx(uiCPage, 0, &cpInfEx))
54 {
55 _tcscpy(lpCPage->Name, cpInfEx.CodePageName);
56 }
57 else if (!SetupGetStringField(&infCont, 1, lpCPage->Name, MAX_PATH, NULL))
58 {
59 GlobalUnlock(hCPage);
60 GlobalFree(hCPage);
61 continue;
62 }
63
64 lpCPage->NextItem = PCPage;
65 PCPage = lpCPage;
66 }
67 }
68
69 return TRUE;
70 }
71
72 static BOOL CALLBACK
73 InstalledCPProc(LPTSTR lpStr)
74 {
75 LPCPAGE lpCP;
76 UINT uiCP;
77
78 lpCP = PCPage;
79 uiCP = _ttol(lpStr);
80
81 for (;;)
82 {
83 if (!lpCP) break;
84 if (lpCP->CPage == uiCP)
85 {
86 lpCP->Status |= 0x0001;
87 break;
88 }
89 lpCP = lpCP->NextItem;
90 }
91
92 return TRUE;
93 }
94
95 static VOID
96 InitCodePagesList(HWND hwndDlg)
97 {
98 LPCPAGE lpCPage;
99 INT ItemIndex;
100 HWND hList;
101 LV_COLUMN column;
102 LV_ITEM item;
103 RECT ListRect;
104
105 hList = GetDlgItem(hwndDlg, IDC_CONV_TABLES);
106
107 hIntlInf = SetupOpenInfFile(_T("intl.inf"), NULL, INF_STYLE_WIN4, NULL);
108
109 if (hIntlInf == INVALID_HANDLE_VALUE)
110 return;
111
112 if (!SetupOpenAppendInfFile(NULL, hIntlInf, NULL))
113 {
114 SetupCloseInfFile(hIntlInf);
115 hIntlInf = NULL;
116 return;
117 }
118
119 if (!GetSupportedCP())
120 return;
121
122 SetupCloseInfFile(hIntlInf);
123
124 if (!EnumSystemCodePages(InstalledCPProc, CP_INSTALLED))
125 return;
126
127 ZeroMemory(&column, sizeof(LV_COLUMN));
128 column.mask = LVCF_FMT|LVCF_TEXT|LVCF_WIDTH;
129 column.fmt = LVCFMT_LEFT;
130 GetClientRect(hList, &ListRect);
131 column.cx = ListRect.right - GetSystemMetrics(SM_CYHSCROLL);
132 (VOID) ListView_InsertColumn(hList, 0, &column);
133
134 (VOID) ListView_SetExtendedListViewStyle(hList, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT);
135
136 lpCPage = PCPage;
137
138 for (;;)
139 {
140 if (!lpCPage) break;
141 ZeroMemory(&item, sizeof(LV_ITEM));
142 item.mask = LVIF_TEXT|LVIF_PARAM|LVIF_STATE;
143 item.state = 0;
144 item.stateMask = LVIS_STATEIMAGEMASK;
145 item.pszText = lpCPage->Name;
146 item.lParam = (LPARAM)lpCPage;
147
148 ItemIndex = ListView_InsertItem(hList, &item);
149
150 if (ItemIndex >= 0)
151 {
152 if (lpCPage->Status & 0x0001)
153 {
154 ListView_SetItemState(hList, ItemIndex,
155 INDEXTOSTATEIMAGEMASK(LVIS_SELECTED),
156 LVIS_STATEIMAGEMASK);
157 }
158 else
159 {
160 ListView_SetItemState(hList, ItemIndex,
161 INDEXTOSTATEIMAGEMASK(LVIS_FOCUSED),
162 LVIS_STATEIMAGEMASK);
163 }
164 }
165
166 lpCPage = lpCPage->NextItem;
167 }
168 }
169
170 static BOOL CALLBACK
171 LocalesEnumProc(LPTSTR lpLocale)
172 {
173 LCID lcid;
174 TCHAR lang[255];
175 INT index;
176 BOOL bNoShow = FALSE;
177
178 lcid = _tcstoul(lpLocale, NULL, 16);
179
180 if (lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT) ||
181 lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT))
182 {
183 if (bSpain == FALSE)
184 {
185 LoadString(hApplet, IDS_SPAIN, lang, 255);
186 bSpain = TRUE;
187 }
188 else
189 {
190 bNoShow = TRUE;
191 }
192 }
193 else
194 {
195 GetLocaleInfo(lcid, LOCALE_SLANGUAGE, lang, sizeof(lang)/sizeof(TCHAR));
196 }
197
198 if (bNoShow == FALSE)
199 {
200 index = SendMessage(hLangList,
201 CB_ADDSTRING,
202 0,
203 (LPARAM)lang);
204
205 SendMessage(hLangList,
206 CB_SETITEMDATA,
207 index,
208 (LPARAM)lcid);
209 }
210
211 return TRUE;
212 }
213
214 static VOID
215 InitLanguagesList(HWND hwndDlg)
216 {
217 TCHAR langSel[255];
218
219 hLangList = GetDlgItem(hwndDlg, IDC_LANGUAGE_COMBO);
220
221 bSpain = FALSE;
222 EnumSystemLocales(LocalesEnumProc, LCID_SUPPORTED);
223
224 /* Select current locale */
225 GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SLANGUAGE, langSel, sizeof(langSel)/sizeof(TCHAR));
226
227 SendMessage(hLangList, CB_SELECTSTRING, -1, (LPARAM)langSel);
228 }
229
230 static VOID
231 GetCurrentDPI(LPTSTR szDPI)
232 {
233 DWORD dwType, dwSize, dwDPI, dwDefDPI = 0x00000060; // Default 96 DPI
234 HKEY hKey;
235
236 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontDPI"), 0, NULL,
237 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS)
238 {
239 _tcscpy(szDPI, _T("96"));
240 return;
241 }
242
243 dwType = REG_DWORD;
244 dwSize = sizeof(DWORD);
245
246 if (RegQueryValueEx(hKey, _T("LogPixels"), NULL, &dwType, (LPBYTE)&dwDPI, &dwSize) != ERROR_SUCCESS)
247 {
248 if (RegSetValueEx(hKey, _T("LogPixels"), 0, REG_DWORD, (LPBYTE)&dwDefDPI, sizeof(DWORD)) == ERROR_SUCCESS)
249 {
250 _tcscpy(szDPI, _T("96"));
251 RegCloseKey(hKey);
252 return;
253 }
254 }
255 else wsprintf(szDPI, _T("%d"), dwDPI);
256
257 RegCloseKey(hKey);
258 }
259
260 VOID
261 SetNonUnicodeLang(HWND hwnd, LCID lcid)
262 {
263 TCHAR szDefCP[5 + 1], szSection[MAX_PATH], szDPI[3 + 1];
264 HINF hFontInf;
265 UINT Count;
266
267 GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, szDefCP, sizeof(szDefCP) / sizeof(TCHAR));
268 GetCurrentDPI(szDPI);
269
270 wsprintf(szSection, _T("Font.CP%s.%s"), szDefCP, szDPI);
271
272 hFontInf = SetupOpenInfFile(_T("font.inf"), NULL, INF_STYLE_WIN4, NULL);
273
274 if (hFontInf == INVALID_HANDLE_VALUE)
275 return;
276
277 if (!SetupOpenAppendInfFile(NULL, hFontInf, NULL))
278 {
279 SetupCloseInfFile(hFontInf);
280 return;
281 }
282
283 Count = (UINT) SetupGetLineCount(hFontInf, szSection);
284 if (Count <= 0) return;
285
286 if (!SetupInstallFromInfSection(hwnd, hFontInf, szSection, SPINST_REGISTRY & ~SPINST_FILES,
287 NULL, NULL, 0, NULL, NULL, NULL, NULL))
288 MessageBox(hwnd, _T("Unable to install a new language for programs don't support unicode!"),
289 NULL, MB_ICONERROR | MB_OK);
290
291 SetupCloseInfFile(hFontInf);
292 }
293
294 /* Property page dialog callback */
295 INT_PTR CALLBACK
296 AdvancedPageProc(HWND hwndDlg,
297 UINT uMsg,
298 WPARAM wParam,
299 LPARAM lParam)
300 {
301 switch(uMsg)
302 {
303 case WM_INITDIALOG:
304 {
305 InitLanguagesList(hwndDlg);
306 InitCodePagesList(hwndDlg);
307 }
308 break;
309
310 case WM_COMMAND:
311 {
312 switch (LOWORD(wParam))
313 {
314 case IDC_LANGUAGE_COMBO:
315 {
316 if (HIWORD(wParam) == CBN_SELCHANGE)
317 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
318 }
319 break;
320 }
321 }
322 break;
323
324 case WM_NOTIFY:
325 {
326 LPNMHDR lpnm = (LPNMHDR)lParam;
327
328 if (lpnm->code == (UINT)PSN_APPLY)
329 {
330 LCID lcid;
331 INT iIndex;
332
333 PropSheet_UnChanged(GetParent(hwndDlg), hwndDlg);
334
335 iIndex = SendMessage(hLangList, CB_GETCURSEL, 0, 0);
336 if (iIndex == CB_ERR)
337 break;
338
339 lcid = SendMessage(hLangList, CB_GETITEMDATA, iIndex, 0);
340 if (lcid == (LCID)CB_ERR)
341 break;
342
343 SetNonUnicodeLang(hwndDlg, lcid);
344 }
345 }
346 break;
347 }
348
349 return FALSE;
350 }
351
352 /* EOF */