3 * FILE: dll/cpl/input/layout_list.c
5 * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
8 #include "layout_list.h"
11 static LAYOUT_LIST_NODE
*_LayoutList
= NULL
;
14 static LAYOUT_LIST_NODE
*
15 LayoutList_AppendNode(DWORD dwId
, DWORD dwSpecialId
, const WCHAR
*pszName
)
17 LAYOUT_LIST_NODE
*pCurrent
;
18 LAYOUT_LIST_NODE
*pNew
;
23 pCurrent
= _LayoutList
;
25 pNew
= (LAYOUT_LIST_NODE
*)malloc(sizeof(LAYOUT_LIST_NODE
));
29 ZeroMemory(pNew
, sizeof(LAYOUT_LIST_NODE
));
31 pNew
->pszName
= _wcsdup(pszName
);
32 if (pNew
->pszName
== NULL
)
39 pNew
->dwSpecialId
= dwSpecialId
;
47 while (pCurrent
->pNext
!= NULL
)
49 pCurrent
= pCurrent
->pNext
;
52 pNew
->pPrev
= pCurrent
;
53 pCurrent
->pNext
= pNew
;
61 LayoutList_Destroy(VOID
)
63 LAYOUT_LIST_NODE
*pCurrent
;
65 if (_LayoutList
== NULL
)
68 pCurrent
= _LayoutList
;
70 while (pCurrent
!= NULL
)
72 LAYOUT_LIST_NODE
*pNext
= pCurrent
->pNext
;
74 free(pCurrent
->pszName
);
85 LayoutList_Create(VOID
)
87 WCHAR szSystemDirectory
[MAX_PATH
];
88 WCHAR szLayoutId
[MAX_PATH
];
93 if (!GetSystemDirectoryW(szSystemDirectory
, ARRAYSIZE(szSystemDirectory
)))
98 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
99 L
"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts",
101 KEY_ENUMERATE_SUB_KEYS
,
102 &hKey
) != ERROR_SUCCESS
)
107 dwSize
= ARRAYSIZE(szLayoutId
);
109 while (RegEnumKeyExW(hKey
, dwIndex
, szLayoutId
, &dwSize
,
110 NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
114 if (RegOpenKeyExW(hKey
,
118 &hLayoutKey
) == ERROR_SUCCESS
)
120 WCHAR szBuffer
[MAX_PATH
];
122 dwSize
= sizeof(szBuffer
);
124 if (RegQueryValueExW(hLayoutKey
,
127 (LPBYTE
)szBuffer
, &dwSize
) == ERROR_SUCCESS
)
129 WCHAR szFilePath
[MAX_PATH
];
131 StringCchPrintfW(szFilePath
, ARRAYSIZE(szFilePath
),
132 L
"%s\\%s", szSystemDirectory
, szBuffer
);
134 if (GetFileAttributesW(szFilePath
) != INVALID_FILE_ATTRIBUTES
)
136 DWORD dwSpecialId
= 0;
138 dwSize
= sizeof(szBuffer
);
140 if (RegQueryValueExW(hLayoutKey
,
143 (LPBYTE
)szBuffer
, &dwSize
) == ERROR_SUCCESS
)
145 dwSpecialId
= DWORDfromString(szBuffer
);
148 dwSize
= sizeof(szBuffer
);
150 if (RegQueryValueExW(hLayoutKey
,
151 L
"Layout Display Name",
153 (LPBYTE
)szBuffer
, &dwSize
) == ERROR_SUCCESS
&&
159 /* Move to the position after the character "@" */
160 pBuffer
= szBuffer
+ 1;
162 /* Get a pointer to the beginning ",-" */
163 pIndex
= wcsstr(pBuffer
, L
",-");
167 WCHAR szPath
[MAX_PATH
];
170 /* Convert the number in the string after the ",-" */
171 iIndex
= _wtoi(pIndex
+ 2);
175 if (ExpandEnvironmentStringsW(pBuffer
, szPath
, ARRAYSIZE(szPath
)) != 0)
179 hHandle
= LoadLibraryW(szPath
);
182 INT iLength
= LoadStringW(hHandle
, iIndex
, szBuffer
, ARRAYSIZE(szBuffer
));
184 FreeLibrary(hHandle
);
188 DWORD dwLayoutId
= DWORDfromString(szLayoutId
);
190 LayoutList_AppendNode(dwLayoutId
, dwSpecialId
, szBuffer
);
215 dwSize
= sizeof(szBuffer
);
217 if (RegQueryValueExW(hLayoutKey
,
220 (LPBYTE
)szBuffer
, &dwSize
) == ERROR_SUCCESS
)
222 DWORD dwLayoutId
= DWORDfromString(szLayoutId
);
224 LayoutList_AppendNode(dwLayoutId
, dwSpecialId
, szBuffer
);
230 RegCloseKey(hLayoutKey
);
233 dwSize
= ARRAYSIZE(szLayoutId
);
242 LayoutList_GetByHkl(HKL hkl
)
244 LAYOUT_LIST_NODE
*pCurrent
;
246 if ((HIWORD(hkl
) & 0xF000) == 0xF000)
248 DWORD dwSpecialId
= (HIWORD(hkl
) & 0x0FFF);
250 for (pCurrent
= _LayoutList
; pCurrent
!= NULL
; pCurrent
= pCurrent
->pNext
)
252 if (dwSpecialId
== pCurrent
->dwSpecialId
)
260 for (pCurrent
= _LayoutList
; pCurrent
!= NULL
; pCurrent
= pCurrent
->pNext
)
262 if (HIWORD(hkl
) == LOWORD(pCurrent
->dwId
))
274 LayoutList_GetFirst(VOID
)