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