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