2 * PROJECT: ReactOS International Control Panel
3 * FILE: dll/cpl/intl/kblayouts.c
4 * PURPOSE: Functions for manipulation with keyboard layouts
5 * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
10 /* Character Count of a layout ID like "00000409" */
11 #define CCH_LAYOUT_ID 8
13 /* Maximum Character Count of a ULONG in decimal */
14 #define CCH_ULONG_DEC 10
17 /* szLayoutID like 00000409, szLangID like 00000409 */
19 IsLayoutExists(LPTSTR szLayoutID
, LPTSTR szLangID
)
22 TCHAR szPreload
[CCH_LAYOUT_ID
+ 1], szLayoutNum
[3 + 1],
23 szTmp
[CCH_LAYOUT_ID
+ 1], szOldLangID
[CCH_LAYOUT_ID
+ 1];
24 DWORD dwIndex
= 0, dwType
, dwSize
;
25 BOOL IsLangExists
= FALSE
;
28 if (RegOpenKeyEx(HKEY_CURRENT_USER
, _T("Keyboard Layout\\Preload"),
29 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
31 dwSize
= sizeof(szLayoutNum
);
33 while (RegEnumValue(hKey
, dwIndex
, szLayoutNum
, &dwSize
, NULL
, &dwType
, NULL
, NULL
) == ERROR_SUCCESS
)
35 dwSize
= sizeof(szPreload
);
36 if (RegQueryValueEx(hKey
, szLayoutNum
, NULL
, NULL
, (LPBYTE
)szPreload
, &dwSize
) != ERROR_SUCCESS
)
42 langid
= (LANGID
)_tcstoul(szPreload
, NULL
, 16);
43 GetLocaleInfo(langid
, LOCALE_ILANGUAGE
, szTmp
, sizeof(szTmp
) / sizeof(TCHAR
));
44 wsprintf(szOldLangID
, _T("0000%s"), szTmp
);
46 if (_tcscmp(szOldLangID
, szLangID
) == 0)
51 if (szPreload
[0] == 'd')
53 if (RegOpenKeyEx(HKEY_CURRENT_USER
, _T("Keyboard Layout\\Substitutes"),
54 0, KEY_QUERY_VALUE
, &hSubKey
) == ERROR_SUCCESS
)
56 dwSize
= sizeof(szTmp
);
57 RegQueryValueEx(hSubKey
, szPreload
, NULL
, NULL
, (LPBYTE
)szTmp
, &dwSize
);
59 if ((_tcscmp(szTmp
, szLayoutID
) == 0)&&(IsLangExists
))
69 if ((_tcscmp(szPreload
, szLayoutID
) == 0) && (IsLangExists
))
77 dwSize
= sizeof(szLayoutNum
);
88 GetLayoutCount(LPTSTR szLang
)
91 TCHAR szLayoutID
[3 + 1], szPreload
[CCH_LAYOUT_ID
+ 1], szLOLang
[MAX_PATH
];
92 DWORD dwIndex
= 0, dwType
, dwSize
;
95 if (RegOpenKeyEx(HKEY_CURRENT_USER
, _T("Keyboard Layout\\Preload"),
96 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
98 dwSize
= sizeof(szLayoutID
);
100 while (RegEnumValue(hKey
, dwIndex
, szLayoutID
, &dwSize
, NULL
, &dwType
, NULL
, NULL
) == ERROR_SUCCESS
)
102 dwSize
= sizeof(szPreload
);
103 RegQueryValueEx(hKey
, szLayoutID
, NULL
, NULL
, (LPBYTE
)szPreload
, &dwSize
);
105 for (i
= 4, j
= 0; i
< _tcslen(szPreload
)+1; i
++, j
++)
106 szLOLang
[j
] = szPreload
[i
];
108 if (_tcscmp(szLOLang
, szLang
) == 0) Count
+= 1;
110 dwSize
= sizeof(szLayoutID
);
120 /* szLayoutID like 00000409, szLangID like 00000409 */
122 AddNewLayout(LPTSTR szLayoutID
, LPTSTR szLangID
)
124 TCHAR NewLayout
[CCH_ULONG_DEC
+ 1], Lang
[MAX_PATH
],
125 LangID
[CCH_LAYOUT_ID
+ 1], SubPath
[CCH_LAYOUT_ID
+ 1];
130 if (RegOpenKeyEx(HKEY_CURRENT_USER
, _T("Keyboard Layout\\Preload"), 0, KEY_ALL_ACCESS
, &hKey
) == ERROR_SUCCESS
)
132 if (RegQueryInfoKey(hKey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &cValues
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
134 _ultot(cValues
+ 1, NewLayout
, 10);
136 lcid
= _tcstoul(szLangID
, NULL
, 16);
138 GetLocaleInfo(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Lang
, sizeof(Lang
) / sizeof(TCHAR
));
139 wsprintf(LangID
, _T("0000%s"), Lang
);
141 if (IsLayoutExists(szLayoutID
, LangID
))
147 if (GetLayoutCount(Lang
) >= 1)
149 wsprintf(SubPath
, _T("d%03d%s"), GetLayoutCount(Lang
), Lang
);
151 else if ((_tcscmp(LangID
, szLayoutID
) != 0) && (GetLayoutCount(Lang
) == 0))
153 wsprintf(SubPath
, _T("d%03d%s"), 0, Lang
);
155 else SubPath
[0] = '\0';
157 if (_tcslen(SubPath
) != 0)
159 if (RegCreateKeyEx(HKEY_CURRENT_USER
, _T("Keyboard Layout\\Substitutes"), 0, NULL
,
160 REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
,
161 NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
163 if (RegSetValueEx(hSubKey
, SubPath
, 0, REG_SZ
, (LPBYTE
)szLayoutID
,
164 (DWORD
)((CCH_LAYOUT_ID
+ 1) * sizeof(TCHAR
))) != ERROR_SUCCESS
)
166 RegCloseKey(hSubKey
);
170 RegCloseKey(hSubKey
);
172 lstrcpy(szLayoutID
, SubPath
);
180 (DWORD
)((CCH_LAYOUT_ID
+ 1) * sizeof(TCHAR
)));
189 AddNewKbLayoutsByLcid(LCID Lcid
)
192 TCHAR szLang
[CCH_LAYOUT_ID
+ 1], szLangID
[CCH_LAYOUT_ID
+ 1];
193 TCHAR szLangStr
[MAX_STR_SIZE
], szLayoutStr
[MAX_STR_SIZE
], szStr
[MAX_STR_SIZE
];
194 INFCONTEXT InfContext
;
196 DWORD FieldCount
, Index
;
198 GetLocaleInfo(MAKELCID(Lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, szLang
, sizeof(szLang
) / sizeof(TCHAR
));
199 wsprintf(szLangID
, _T("0000%s"), szLang
);
201 hIntlInf
= SetupOpenInfFile(_T("intl.inf"), NULL
, INF_STYLE_WIN4
, NULL
);
203 if (hIntlInf
== INVALID_HANDLE_VALUE
)
206 if (!SetupOpenAppendInfFile(NULL
, hIntlInf
, NULL
))
208 SetupCloseInfFile(hIntlInf
);
213 Count
= SetupGetLineCount(hIntlInf
, _T("Locales"));
214 if (Count
<= 0) return;
216 if (SetupFindFirstLine(hIntlInf
, _T("Locales"), szLangID
, &InfContext
))
218 FieldCount
= SetupGetFieldCount(&InfContext
);
222 for (Index
= 5; Index
<= FieldCount
; Index
++)
224 if (SetupGetStringField(&InfContext
, Index
, szStr
, MAX_STR_SIZE
, NULL
))
228 if (_tcslen(szStr
) != 13) continue;
230 wsprintf(szLangStr
, _T("0000%s"), szStr
);
233 for (i
= 5, j
= 0; i
<= _tcslen(szStr
); i
++, j
++)
234 szLayoutStr
[j
] = szStr
[i
];
236 AddNewLayout(szLayoutStr
, szLangStr
);
241 SetupCloseInfFile(hIntlInf
);