Synchronize with trunk r58528.
[reactos.git] / 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 = SetupGetLineCount(hIntlInf, _T("CodePages"));
29 if (Count <= 0) return FALSE;
30
31 for (Number = 0; Number < (UINT)Count; Number++)
32 {
33 if (SetupGetLineByIndex(hIntlInf, _T("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 _tcscpy(lpCPage->Name, cpInfEx.CodePageName);
47 }
48 else if (!SetupGetStringField(&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(LPTSTR lpStr)
65 {
66 LPCPAGE lpCP;
67 UINT uiCP;
68
69 lpCP = PCPage;
70 uiCP = _ttol(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 = SetupOpenInfFile(_T("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(LPTSTR lpLocale)
163 {
164 LCID lcid;
165 TCHAR lang[255];
166 INT index;
167 BOOL bNoShow = FALSE;
168
169 lcid = _tcstoul(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 LoadString(hApplet, IDS_SPAIN, lang, 255);
177 bSpain = TRUE;
178 }
179 else
180 {
181 bNoShow = TRUE;
182 }
183 }
184 else
185 {
186 GetLocaleInfo(lcid, LOCALE_SLANGUAGE, lang, sizeof(lang)/sizeof(TCHAR));
187 }
188
189 if (bNoShow == FALSE)
190 {
191 index = SendMessage(hLangList,
192 CB_ADDSTRING,
193 0,
194 (LPARAM)lang);
195
196 SendMessage(hLangList,
197 CB_SETITEMDATA,
198 index,
199 (LPARAM)lcid);
200 }
201
202 return TRUE;
203 }
204
205 static VOID
206 InitLanguagesList(HWND hwndDlg)
207 {
208 TCHAR langSel[255];
209
210 hLangList = GetDlgItem(hwndDlg, IDC_LANGUAGE_COMBO);
211
212 bSpain = FALSE;
213 EnumSystemLocales(LocalesEnumProc, LCID_SUPPORTED);
214
215 /* Select current locale */
216 GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SLANGUAGE, langSel, sizeof(langSel)/sizeof(TCHAR));
217
218 SendMessage(hLangList, CB_SELECTSTRING, -1, (LPARAM)langSel);
219 }
220
221 static VOID
222 GetCurrentDPI(LPTSTR szDPI)
223 {
224 DWORD dwType, dwSize, dwDPI, dwDefDPI = 0x00000060; // Default 96 DPI
225 HKEY hKey;
226
227 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontDPI"), 0, NULL,
228 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS)
229 {
230 _tcscpy(szDPI, _T("96"));
231 return;
232 }
233
234 dwType = REG_DWORD;
235 dwSize = sizeof(DWORD);
236
237 if (RegQueryValueEx(hKey, _T("LogPixels"), NULL, &dwType, (LPBYTE)&dwDPI, &dwSize) != ERROR_SUCCESS)
238 {
239 if (RegSetValueEx(hKey, _T("LogPixels"), 0, REG_DWORD, (LPBYTE)&dwDefDPI, sizeof(DWORD)) == ERROR_SUCCESS)
240 {
241 _tcscpy(szDPI, _T("96"));
242 RegCloseKey(hKey);
243 return;
244 }
245 }
246 else wsprintf(szDPI, _T("%d"), dwDPI);
247
248 RegCloseKey(hKey);
249 }
250
251 VOID
252 SetNonUnicodeLang(HWND hwnd, LCID lcid)
253 {
254 TCHAR szDefCP[5 + 1], szSection[MAX_PATH], szDPI[3 + 1];
255 HINF hFontInf;
256 UINT Count;
257
258 GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, szDefCP, sizeof(szDefCP) / sizeof(TCHAR));
259 GetCurrentDPI(szDPI);
260
261 wsprintf(szSection, _T("Font.CP%s.%s"), szDefCP, szDPI);
262
263 hFontInf = SetupOpenInfFile(_T("font.inf"), NULL, INF_STYLE_WIN4, NULL);
264
265 if (hFontInf == INVALID_HANDLE_VALUE)
266 return;
267
268 if (!SetupOpenAppendInfFile(NULL, hFontInf, NULL))
269 {
270 SetupCloseInfFile(hFontInf);
271 return;
272 }
273
274 Count = (UINT) SetupGetLineCount(hFontInf, szSection);
275 if (Count <= 0) return;
276
277 if (!SetupInstallFromInfSection(hwnd, hFontInf, szSection, SPINST_REGISTRY & ~SPINST_FILES,
278 NULL, NULL, 0, NULL, NULL, NULL, NULL))
279 MessageBox(hwnd, _T("Unable to install a new language for programs don't support unicode!"),
280 NULL, MB_ICONERROR | MB_OK);
281
282 SetupCloseInfFile(hFontInf);
283 }
284
285 /* Property page dialog callback */
286 INT_PTR CALLBACK
287 AdvancedPageProc(HWND hwndDlg,
288 UINT uMsg,
289 WPARAM wParam,
290 LPARAM lParam)
291 {
292 switch(uMsg)
293 {
294 case WM_INITDIALOG:
295 {
296 InitLanguagesList(hwndDlg);
297 InitCodePagesList(hwndDlg);
298 }
299 break;
300
301 case WM_COMMAND:
302 {
303 switch (LOWORD(wParam))
304 {
305 case IDC_LANGUAGE_COMBO:
306 {
307 if (HIWORD(wParam) == CBN_SELCHANGE)
308 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
309 }
310 break;
311 }
312 }
313 break;
314
315 case WM_NOTIFY:
316 {
317 LPNMHDR lpnm = (LPNMHDR)lParam;
318
319 if (lpnm->code == (UINT)PSN_APPLY)
320 {
321 LCID lcid;
322 INT iIndex;
323
324 PropSheet_UnChanged(GetParent(hwndDlg), hwndDlg);
325
326 iIndex = SendMessage(hLangList, CB_GETCURSEL, 0, 0);
327 if (iIndex == CB_ERR)
328 break;
329
330 lcid = SendMessage(hLangList, CB_GETITEMDATA, iIndex, 0);
331 if (lcid == (LCID)CB_ERR)
332 break;
333
334 SetNonUnicodeLang(hwndDlg, lcid);
335 }
336 }
337 break;
338 }
339
340 return FALSE;
341 }
342
343 /* EOF */