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?re…
==============================================================================
--- 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=38…
==============================================================================
--- 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?r…
==============================================================================
--- 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?r…
==============================================================================
--- 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(a)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