2 * FreeRDP: A Remote Desktop Protocol Implementation
5 * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
28 #include <winpr/crt.h>
29 #include <winpr/input.h>
31 #include "liblocale.h"
33 #include <freerdp/locale/locale.h>
34 #include <freerdp/locale/keyboard.h>
36 #include "keyboard_x11.h"
37 #include "xkb_layout_ids.h"
39 int freerdp_detect_keyboard_layout_from_xkb(DWORD* keyboardLayoutId)
49 /* We start by looking for _XKB_RULES_NAMES_BACKUP which appears to be used by libxklavier */
51 if (!(xprop = popen("xprop -root _XKB_RULES_NAMES_BACKUP", "r")))
54 /* Sample output for "Canadian Multilingual Standard"
56 * _XKB_RULES_NAMES_BACKUP(STRING) = "xorg", "pc105", "ca", "multix", ""
57 * Where "xorg" is the set of rules
58 * "pc105" the keyboard type
59 * "ca" the keyboard layout
60 * "multi" the keyboard layout variant
63 while (fgets(buffer, sizeof(buffer), xprop) != NULL)
65 if ((pch = strstr(buffer, "_XKB_RULES_NAMES_BACKUP(STRING) = ")) != NULL)
68 pch = strchr(&buffer[34], ','); /* We assume it is xorg */
72 pch = strchr(pch, ',');
75 beg = strchr(pch + 1, '"');
78 end = strchr(beg, '"');
84 beg = strchr(end + 1, '"');
87 end = strchr(beg, '"');
96 DEBUG_KBD("_XKB_RULES_NAMES_BACKUP layout: %s, variant: %s", layout, variant);
97 *keyboardLayoutId = find_keyboard_layout_in_xorg_rules(layout, variant);
99 if (*keyboardLayoutId > 0)
102 /* Check _XKB_RULES_NAMES if _XKB_RULES_NAMES_BACKUP fails */
104 if (!(xprop = popen("xprop -root _XKB_RULES_NAMES", "r")))
107 while (fgets(buffer, sizeof(buffer), xprop) != NULL)
109 if ((pch = strstr(buffer, "_XKB_RULES_NAMES(STRING) = ")) != NULL)
112 pch = strchr(&buffer[27], ','); // We assume it is xorg
116 pch = strchr(pch, ',');
119 beg = strchr(pch + 1, '"');
122 end = strchr(beg, '"');
128 beg = strchr(end + 1, '"');
131 end = strchr(beg, '"');
140 DEBUG_KBD("_XKB_RULES_NAMES layout: %s, variant: %s", layout, variant);
141 *keyboardLayoutId = find_keyboard_layout_in_xorg_rules(layout, variant);
143 if (*keyboardLayoutId > 0)
144 return *keyboardLayoutId;
149 char* freerdp_detect_keymap_from_xkb()
159 /* this tells us about the current XKB configuration, if XKB is available */
160 setxkbmap = popen("setxkbmap -print", "r");
165 while (fgets(buffer, sizeof(buffer), setxkbmap) != NULL)
167 /* the line with xkb_keycodes is what interests us */
168 pch = strstr(buffer, "xkb_keycodes");
172 pch = strstr(pch, "include");
176 /* check for " " delimiter presence */
177 if ((beg = strchr(pch, '"')) == NULL)
182 if ((pch = strchr(beg + 1, '"')) == NULL)
185 end = strcspn(beg + 1, "\"") + beg + 1;
188 length = (end - beg);
189 keymap = (char*) malloc(length + 1);
191 strncpy(keymap, beg, length);
192 keymap[length] = '\0';