Author: dchapyshev Date: Tue Jan 20 09:13:32 2009 New Revision: 38977
URL: http://svn.reactos.org/svn/reactos?rev=38977&view=rev Log: - Implement auto add keyboard layouts
Added: trunk/reactos/dll/cpl/intl/kblayouts.c (with props) Modified: trunk/reactos/dll/cpl/intl/generalp.c trunk/reactos/dll/cpl/intl/intl.h trunk/reactos/dll/cpl/intl/intl.rbuild
Modified: trunk/reactos/dll/cpl/intl/generalp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/intl/generalp.c?rev... ============================================================================== --- trunk/reactos/dll/cpl/intl/generalp.c [iso-8859-1] (original) +++ trunk/reactos/dll/cpl/intl/generalp.c [iso-8859-1] Tue Jan 20 09:13:32 2009 @@ -28,7 +28,6 @@
#include <windows.h> #include <commctrl.h> -#include <cpl.h> #include <tchar.h> #include <stdio.h>
@@ -441,6 +440,7 @@
/* Set new locale */ SetNewLocale(NewLcid); + AddNewKbLayoutsByLcid(NewLcid); SetUserGeoID(NewGeoID); SetNonUnicodeLang(hwndDlg, NewLcid); }
Modified: trunk/reactos/dll/cpl/intl/intl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/intl/intl.h?rev=389... ============================================================================== --- trunk/reactos/dll/cpl/intl/intl.h [iso-8859-1] (original) +++ trunk/reactos/dll/cpl/intl/intl.h [iso-8859-1] Tue Jan 20 09:13:32 2009 @@ -1,5 +1,7 @@ #ifndef __CPL_INTL_H #define __CPL_INTL_H + +#include <cpl.h>
#define MAX_FMT_SIZE 30 #define MAX_STR_SIZE 128 @@ -77,6 +79,9 @@ APIENTRY SetupApplet(HWND hwndDlg, LCID lcid);
+/* kblayouts.c */ +VOID AddNewKbLayoutsByLcid(LCID Lcid); + #endif /* __CPL_INTL_H */
/* EOF */
Modified: trunk/reactos/dll/cpl/intl/intl.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/intl/intl.rbuild?re... ============================================================================== --- trunk/reactos/dll/cpl/intl/intl.rbuild [iso-8859-1] (original) +++ trunk/reactos/dll/cpl/intl/intl.rbuild [iso-8859-1] Tue Jan 20 09:13:32 2009 @@ -17,6 +17,7 @@ <file>numbers.c</file> <file>time.c</file> <file>misc.c</file> + <file>kblayouts.c</file> <file>languages.c</file> <file>advanced.c</file> <file>sort.c</file>
Added: trunk/reactos/dll/cpl/intl/kblayouts.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/intl/kblayouts.c?re... ============================================================================== --- trunk/reactos/dll/cpl/intl/kblayouts.c (added) +++ trunk/reactos/dll/cpl/intl/kblayouts.c [iso-8859-1] Tue Jan 20 09:13:32 2009 @@ -1,0 +1,249 @@ +/* + * PROJECT: ReactOS International Control Panel + * FILE: dll/cpl/intl/kblayouts.c + * PURPOSE: Functions for manipulation with keyboard layouts + * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org) + */ + +#include <windows.h> +#include <setupapi.h> +#include <tchar.h> +#include <stdio.h> + +#include "intl.h" +#include "resource.h" + +/* Character Count of a layout ID like "00000409" */ +#define CCH_LAYOUT_ID 8 + +/* Maximum Character Count of a ULONG in decimal */ +#define CCH_ULONG_DEC 10 + + +/* szLayoutID like 00000409, szLangID like 00000409 */ +static BOOL +IsLayoutExists(LPTSTR szLayoutID, LPTSTR szLangID) +{ + HKEY hKey, hSubKey; + TCHAR szPreload[CCH_LAYOUT_ID + 1], szLayoutNum[3 + 1], + szTmp[CCH_LAYOUT_ID + 1], szOldLangID[CCH_LAYOUT_ID + 1]; + DWORD dwIndex = 0, dwType, dwSize; + BOOL IsLangExists = FALSE; + LANGID langid; + + if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\Preload"), + 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + dwSize = sizeof(szLayoutNum); + + while (RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS) + { + dwSize = sizeof(szPreload); + if (RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szPreload, &dwSize) != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return FALSE; + } + + langid = (LANGID)_tcstoul(szPreload, NULL, 16); + GetLocaleInfo(langid, LOCALE_ILANGUAGE, szTmp, sizeof(szTmp) / sizeof(TCHAR)); + wsprintf(szOldLangID, _T("0000%s"), szTmp); + + if (_tcscmp(szOldLangID, szLangID) == 0) + IsLangExists = TRUE; + else + IsLangExists = FALSE; + + if (szPreload[0] == 'd') + { + if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\Substitutes"), + 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS) + { + dwSize = sizeof(szTmp); + RegQueryValueEx(hSubKey, szPreload, NULL, NULL, (LPBYTE)szTmp, &dwSize); + + if ((_tcscmp(szTmp, szLayoutID) == 0)&&(IsLangExists)) + { + RegCloseKey(hSubKey); + RegCloseKey(hKey); + return TRUE; + } + } + } + else + { + if ((_tcscmp(szPreload, szLayoutID) == 0) && (IsLangExists)) + { + RegCloseKey(hKey); + return TRUE; + } + } + + IsLangExists = FALSE; + dwSize = sizeof(szLayoutNum); + dwIndex++; + } + + RegCloseKey(hKey); + } + + return FALSE; +} + +static INT +GetLayoutCount(LPTSTR szLang) +{ + HKEY hKey; + TCHAR szLayoutID[3 + 1], szPreload[CCH_LAYOUT_ID + 1], szLOLang[MAX_PATH]; + DWORD dwIndex = 0, dwType, dwSize; + UINT Count = 0, i, j; + + if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\Preload"), + 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + dwSize = sizeof(szLayoutID); + + while (RegEnumValue(hKey, dwIndex, szLayoutID, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS) + { + dwSize = sizeof(szPreload); + RegQueryValueEx(hKey, szLayoutID, NULL, NULL, (LPBYTE)szPreload, &dwSize); + + for (i = 4, j = 0; i < _tcslen(szPreload)+1; i++, j++) + szLOLang[j] = szPreload[i]; + + if (_tcscmp(szLOLang, szLang) == 0) Count += 1; + + dwSize = sizeof(szLayoutID); + dwIndex++; + } + + RegCloseKey(hKey); + } + + return Count; +} + +/* szLayoutID like 00000409, szLangID like 00000409 */ +static BOOL +AddNewLayout(LPTSTR szLayoutID, LPTSTR szLangID) +{ + TCHAR NewLayout[CCH_ULONG_DEC + 1], Lang[MAX_PATH], + LangID[CCH_LAYOUT_ID + 1], SubPath[CCH_LAYOUT_ID + 1]; + HKEY hKey, hSubKey; + DWORD cValues; + LCID lcid; + + if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\Preload"), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) + { + if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + _ultot(cValues + 1, NewLayout, 10); + + lcid = _tcstoul(szLangID, NULL, 16); + + GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Lang, sizeof(Lang) / sizeof(TCHAR)); + wsprintf(LangID, _T("0000%s"), Lang); + + if (IsLayoutExists(szLayoutID, LangID)) + { + RegCloseKey(hKey); + return FALSE; + } + + if (GetLayoutCount(Lang) >= 1) + { + wsprintf(SubPath, _T("d%03d%s"), GetLayoutCount(Lang), Lang); + } + else if ((_tcscmp(LangID, szLayoutID) != 0) && (GetLayoutCount(Lang) == 0)) + { + wsprintf(SubPath, _T("d%03d%s"), 0, Lang); + } + else SubPath[0] = '\0'; + + if (_tcslen(SubPath) != 0) + { + if (RegCreateKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\Substitutes"), 0, NULL, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, + NULL, &hSubKey, NULL) == ERROR_SUCCESS) + { + if (RegSetValueEx(hSubKey, SubPath, 0, REG_SZ, (LPBYTE)szLayoutID, + (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR))) != ERROR_SUCCESS) + { + RegCloseKey(hSubKey); + RegCloseKey(hKey); + return FALSE; + } + RegCloseKey(hSubKey); + } + lstrcpy(szLayoutID, SubPath); + } + + RegSetValueEx(hKey, + NewLayout, + 0, + REG_SZ, + (LPBYTE)szLayoutID, + (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR))); + } + RegCloseKey(hKey); + } + + return TRUE; +} + +VOID +AddNewKbLayoutsByLcid(LCID Lcid) +{ + HINF hIntlInf; + TCHAR szLang[CCH_LAYOUT_ID + 1], szLangID[CCH_LAYOUT_ID + 1]; + TCHAR szLangStr[MAX_STR_SIZE], szLayoutStr[MAX_STR_SIZE], szStr[MAX_STR_SIZE]; + INFCONTEXT InfContext; + LONG Count; + DWORD FieldCount, Index; + + GetLocaleInfo(MAKELCID(Lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, szLang, sizeof(szLang) / sizeof(TCHAR)); + wsprintf(szLangID, _T("0000%s"), szLang); + + hIntlInf = SetupOpenInfFile(_T("intl.inf"), NULL, INF_STYLE_WIN4, NULL); + + if (hIntlInf == INVALID_HANDLE_VALUE) + return; + + if (!SetupOpenAppendInfFile(NULL, hIntlInf, NULL)) + { + SetupCloseInfFile(hIntlInf); + hIntlInf = NULL; + return; + } + + Count = SetupGetLineCount(hIntlInf, _T("Locales")); + if (Count <= 0) return; + + if (SetupFindFirstLine(hIntlInf, _T("Locales"), szLangID, &InfContext)) + { + FieldCount = SetupGetFieldCount(&InfContext); + + if (FieldCount != 0) + { + for (Index = 5; Index <= FieldCount; Index++) + { + if (SetupGetStringField(&InfContext, Index, szStr, MAX_STR_SIZE, NULL)) + { + INT i, j; + + if (_tcslen(szStr) != 13) continue; + + wsprintf(szLangStr, _T("0000%s"), szStr); + szLangStr[8] = '\0'; + + for (i = 5, j = 0; i <= _tcslen(szStr); i++, j++) + szLayoutStr[j] = szStr[i]; + + AddNewLayout(szLayoutStr, szLangStr); + } + } + } + } + + SetupCloseInfFile(hIntlInf); +}
Propchange: trunk/reactos/dll/cpl/intl/kblayouts.c ------------------------------------------------------------------------------ svn:eol-style = native