Sync with trunk r58033.
[reactos.git] / dll / cpl / input / add.c
1 /*
2 * PROJECT: input.dll
3 * FILE: dll/win32/input/add.c
4 * PURPOSE: input.dll
5 * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
6 * Colin Finck
7 * UPDATE HISTORY:
8 * 06-09-2007 Created
9 */
10
11 #include "resource.h"
12 #include "input.h"
13
14 static HWND hLangList;
15 static HWND hLayoutList;
16
17 static VOID
18 SelectLayoutByLang(VOID)
19 {
20 TCHAR Layout[MAX_PATH], Lang[MAX_PATH], LangID[CCH_LAYOUT_ID + 1];
21 INT iIndex;
22 LCID Lcid;
23
24 iIndex = SendMessage(hLangList, CB_GETCURSEL, 0, 0);
25 Lcid = SendMessage(hLangList, CB_GETITEMDATA, iIndex, 0);
26
27 GetLocaleInfo(MAKELCID(Lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Lang, sizeof(Lang) / sizeof(TCHAR));
28
29 wsprintf(LangID, _T("0000%s"), Lang);
30
31 if (GetLayoutName(LangID, Layout))
32 {
33 SendMessage(hLayoutList, CB_SELECTSTRING,
34 (WPARAM) -1, (LPARAM)Layout);
35 }
36 }
37
38 INT
39 GetLayoutCount(LPTSTR szLang)
40 {
41 HKEY hKey;
42 TCHAR szLayoutID[3 + 1], szPreload[CCH_LAYOUT_ID + 1], szLOLang[MAX_PATH];
43 DWORD dwIndex = 0, dwType, dwSize;
44 UINT Count = 0, i, j;
45
46 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"),
47 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
48 {
49 dwSize = sizeof(szLayoutID);
50
51 while (RegEnumValue(hKey, dwIndex, szLayoutID, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS)
52 {
53 dwSize = sizeof(szPreload);
54 RegQueryValueEx(hKey, szLayoutID, NULL, NULL, (LPBYTE)szPreload, &dwSize);
55
56 for (i = 4, j = 0; i < _tcslen(szPreload)+1; i++, j++)
57 szLOLang[j] = szPreload[i];
58
59 if (_tcscmp(szLOLang, szLang) == 0) Count += 1;
60
61 dwSize = sizeof(szLayoutID);
62 dwIndex++;
63 }
64
65 RegCloseKey(hKey);
66 }
67
68 return Count;
69 }
70
71 static VOID
72 AddNewLayout(HWND hwndDlg)
73 {
74 TCHAR NewLayout[CCH_ULONG_DEC + 1], Lang[MAX_PATH],
75 LangID[CCH_LAYOUT_ID + 1], Layout[MAX_PATH],
76 SubPath[CCH_LAYOUT_ID + 1], szMessage[MAX_PATH];
77 INT iLayout, iLang;
78 HKEY hKey, hSubKey;
79 DWORD cValues;
80 PTSTR pts;
81 LCID lcid;
82
83 iLayout = SendMessage(hLayoutList, CB_GETCURSEL, 0, 0);
84 if (iLayout == CB_ERR) return;
85
86 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
87 {
88 if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
89 {
90 _ultot(cValues + 1, NewLayout, 10);
91
92 iLang = SendMessage(hLangList, CB_GETCURSEL, 0, 0);
93 lcid = SendMessage(hLangList, CB_GETITEMDATA, iLang, 0);
94 pts = (PTSTR) SendMessage(hLayoutList, CB_GETITEMDATA, iLayout, 0);
95
96 GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Lang, sizeof(Lang) / sizeof(TCHAR));
97 wsprintf(LangID, _T("0000%s"), Lang);
98
99 if (IsLayoutExists(pts, LangID))
100 {
101 LoadString(hApplet, IDS_LAYOUT_EXISTS2, szMessage, sizeof(szMessage) / sizeof(TCHAR));
102 MessageBox(hwndDlg, szMessage, NULL, MB_OK | MB_ICONINFORMATION);
103
104 RegCloseKey(hKey);
105 return;
106 }
107
108 if (_tcscmp(LangID, pts) != 0)
109 {
110 if (!GetLayoutName(pts, Layout))
111 {
112 RegCloseKey(hKey);
113 return;
114 }
115 }
116 else
117 {
118 if (!GetLayoutName(LangID, Layout))
119 {
120 RegCloseKey(hKey);
121 return;
122 }
123 }
124
125 if (SendMessage(hLayoutList, CB_SELECTSTRING, (WPARAM) -1, (LPARAM)Layout) != CB_ERR)
126 {
127 if (GetLayoutCount(Lang) >= 1)
128 {
129 wsprintf(SubPath, _T("d%03d%s"), GetLayoutCount(Lang), Lang);
130 }
131 else if ((_tcscmp(LangID, pts) != 0) && (GetLayoutCount(Lang) == 0))
132 {
133 wsprintf(SubPath, _T("d%03d%s"), 0, Lang);
134 }
135 else SubPath[0] = '\0';
136 }
137 else
138 {
139 RegCloseKey(hKey);
140 return;
141 }
142
143 if (_tcslen(SubPath) != 0)
144 {
145 if (RegCreateKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0, NULL,
146 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
147 NULL, &hSubKey, NULL) == ERROR_SUCCESS)
148 {
149 if (RegSetValueEx(hSubKey, SubPath, 0, REG_SZ, (LPBYTE)pts,
150 (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR))) != ERROR_SUCCESS)
151 {
152 RegCloseKey(hSubKey);
153 RegCloseKey(hKey);
154 return;
155 }
156 RegCloseKey(hSubKey);
157 }
158 lstrcpy(pts, SubPath);
159 }
160
161 if (RegSetValueEx(hKey,
162 NewLayout,
163 0,
164 REG_SZ,
165 (LPBYTE)pts,
166 (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR))) == ERROR_SUCCESS)
167 {
168 UpdateLayoutsList();
169 }
170 }
171 RegCloseKey(hKey);
172 }
173 }
174
175 VOID
176 CreateKeyboardLayoutList(HWND hItemsList)
177 {
178 HKEY hKey;
179 PTSTR pstrLayoutID;
180 TCHAR szLayoutID[CCH_LAYOUT_ID + 1], KeyName[MAX_PATH];
181 DWORD dwIndex = 0;
182 DWORD dwSize;
183
184 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\Keyboard Layouts"), 0, KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS)
185 {
186 dwSize = sizeof(szLayoutID) / sizeof(TCHAR);
187
188 while (RegEnumKeyEx(hKey, dwIndex, szLayoutID, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
189 {
190 INT iIndex;
191
192 GetLayoutName(szLayoutID, KeyName);
193
194 iIndex = (INT) SendMessage(hItemsList, CB_ADDSTRING, 0, (LPARAM)KeyName);
195
196 pstrLayoutID = (PTSTR)HeapAlloc(hProcessHeap, 0, sizeof(szLayoutID));
197 lstrcpy(pstrLayoutID, szLayoutID);
198 SendMessage(hItemsList, CB_SETITEMDATA, iIndex, (LPARAM)pstrLayoutID);
199
200 // FIXME!
201 if (_tcscmp(szLayoutID, _T("00000409")) == 0)
202 {
203 SendMessage(hItemsList, CB_SETCURSEL, (WPARAM)iIndex, (LPARAM)0);
204 }
205
206 dwIndex++;
207
208 dwSize = sizeof(szLayoutID) / sizeof(TCHAR);
209 }
210
211 RegCloseKey(hKey);
212 }
213 }
214
215 /* Language enumerate procedure */
216 static BOOL CALLBACK
217 LanguagesEnumProc(LPTSTR lpLanguage)
218 {
219 LCID Lcid;
220 TCHAR Lang[1024];
221 INT Index;
222
223 Lcid = _tcstoul(lpLanguage, NULL, 16);
224
225 GetLocaleInfo(Lcid, LOCALE_SLANGUAGE, Lang, sizeof(Lang));
226 Index = (INT)SendMessage(hLangList, CB_ADDSTRING,
227 0, (LPARAM)Lang);
228
229 SendMessage(hLangList, CB_SETITEMDATA,
230 Index, (LPARAM)Lcid);
231
232 // FIXME!
233 if (Lcid == 0x0409)
234 {
235 SendMessage(hLangList, CB_SELECTSTRING,
236 (WPARAM) -1, (LPARAM)Lang);
237 }
238
239 return TRUE;
240 }
241
242 INT_PTR CALLBACK
243 AddDlgProc(HWND hDlg,
244 UINT message,
245 WPARAM wParam,
246 LPARAM lParam)
247 {
248 UNREFERENCED_PARAMETER(lParam);
249
250 switch (message)
251 {
252 case WM_INITDIALOG:
253 {
254 hLangList = GetDlgItem(hDlg, IDC_INPUT_LANG_COMBO);
255 hLayoutList = GetDlgItem(hDlg, IDC_KEYBOARD_LO_COMBO);
256 EnumSystemLocales(LanguagesEnumProc, LCID_INSTALLED);
257 CreateKeyboardLayoutList(hLayoutList);
258 }
259 break;
260
261 case WM_COMMAND:
262 {
263 switch (LOWORD(wParam))
264 {
265 case IDC_INPUT_LANG_COMBO:
266 {
267 if (HIWORD(wParam) == CBN_SELCHANGE)
268 {
269 SelectLayoutByLang();
270 }
271 }
272 break;
273
274 case IDOK:
275 {
276 AddNewLayout(hDlg);
277 EndDialog(hDlg, LOWORD(wParam));
278 }
279 break;
280
281 case IDCANCEL:
282 {
283 EndDialog(hDlg, LOWORD(wParam));
284 }
285 }
286 }
287 break;
288
289 case WM_DESTROY:
290 {
291 INT iCount;
292
293 for(iCount = SendMessage(hLayoutList, CB_GETCOUNT, 0, 0); --iCount >= 0;)
294 HeapFree(hProcessHeap, 0, (LPVOID)SendMessage(hLayoutList, CB_GETITEMDATA, iCount, 0));
295 }
296 break;
297 }
298
299 return FALSE;
300 }
301
302 /* EOF */