unsigned int detect_keyboard_layout_from_xkb(void *dpy) { char *layout, *variant; unsigned int keyboard_layout = 0, group = 0; XkbRF_VarDefsRec rules_names; XKeyboardState coreKbdState; XkbStateRec state; DEBUG_KBD("display: %p", dpy); if (dpy && XkbRF_GetNamesProp(dpy, NULL, &rules_names)) { DEBUG_KBD("layouts: %s", rules_names.layout); DEBUG_KBD("variants: %s", rules_names.variant); XGetKeyboardControl(dpy, &coreKbdState); if (XkbGetState(dpy, XkbUseCoreKbd, &state) == Success) group = state.group; DEBUG_KBD("group: %d", state.group); layout = comma_substring(rules_names.layout, group); variant = comma_substring(rules_names.variant, group); DEBUG_KBD("layout: %s", layout); DEBUG_KBD("variant: %s", variant); keyboard_layout = find_keyboard_layout_in_xorg_rules(layout, variant); free(rules_names.model); free(rules_names.layout); free(rules_names.variant); free(rules_names.options); } return keyboard_layout; }
int freerdp_detect_keyboard_layout_from_xkb(DWORD* keyboardLayoutId) { char* pch; char* beg; char* end; FILE* xprop; char buffer[1024]; char* layout = NULL; char* variant = NULL; /* We start by looking for _XKB_RULES_NAMES_BACKUP which appears to be used by libxklavier */ xprop = popen("xprop -root _XKB_RULES_NAMES_BACKUP", "r"); /* Sample output for "Canadian Multilingual Standard" * * _XKB_RULES_NAMES_BACKUP(STRING) = "xorg", "pc105", "ca", "multix", "" * Where "xorg" is the set of rules * "pc105" the keyboard type * "ca" the keyboard layout * "multi" the keyboard layout variant */ while (fgets(buffer, sizeof(buffer), xprop) != NULL) { if ((pch = strstr(buffer, "_XKB_RULES_NAMES_BACKUP(STRING) = ")) != NULL) { /* "rules" */ pch = strchr(&buffer[34], ','); /* We assume it is xorg */ pch += 1; /* "type" */ pch = strchr(pch, ','); /* "layout" */ beg = strchr(pch + 1, '"'); beg += 1; end = strchr(beg, '"'); *end = '\0'; layout = beg; /* "variant" */ beg = strchr(end + 1, '"'); beg += 1; end = strchr(beg, '"'); *end = '\0'; variant = beg; } } pclose(xprop); DEBUG_KBD("_XKB_RULES_NAMES_BACKUP layout: %s, variant: %s", layout, variant); *keyboardLayoutId = find_keyboard_layout_in_xorg_rules(layout, variant); if (*keyboardLayoutId > 0) return 0; /* Check _XKB_RULES_NAMES if _XKB_RULES_NAMES_BACKUP fails */ xprop = popen("xprop -root _XKB_RULES_NAMES", "r"); while (fgets(buffer, sizeof(buffer), xprop) != NULL) { if ((pch = strstr(buffer, "_XKB_RULES_NAMES(STRING) = ")) != NULL) { /* "rules" */ pch = strchr(&buffer[27], ','); // We assume it is xorg pch += 1; /* "type" */ pch = strchr(pch, ','); /* "layout" */ beg = strchr(pch + 1, '"'); beg += 1; end = strchr(beg, '"'); *end = '\0'; layout = beg; /* "variant" */ beg = strchr(end + 1, '"'); beg += 1; end = strchr(beg, '"'); *end = '\0'; variant = beg; } } pclose(xprop); DEBUG_KBD("_XKB_RULES_NAMES layout: %s, variant: %s", layout, variant); *keyboardLayoutId = find_keyboard_layout_in_xorg_rules(layout, variant); if (*keyboardLayoutId > 0) return *keyboardLayoutId; return 0; }
static unsigned int detect_keyboard_layout_from_xkb() { FILE* xprop; char* pch; char* beg; char* end; char* layout = NULL; char* variant = NULL; char buffer[1024]; unsigned int keyboard_layout = 0; xprop = popen("xprop -root _XKB_RULES_NAMES", "r"); /* _XKB_RULES_NAMES(STRING) = "evdev", "pc105", "gb", "", "lv3:ralt_switch" */ /* _XKB_RULES_NAMES(STRING) = "evdev", "evdev", "us,dk,gb", ",,", "grp:shift_caps_toggle" */ while(fgets(buffer, sizeof(buffer), xprop) != NULL) { if((pch = strstr(buffer, "_XKB_RULES_NAMES(STRING) = ")) != NULL) { /* Skip "rules" */ pch = strchr(&buffer[27], ','); if (pch == NULL) continue; /* Skip "type" */ pch = strchr(pch + 1, ','); if (pch == NULL) continue; /* Parse "layout" */ beg = strchr(pch + 1, '"'); if (beg == NULL) continue; end = strchr(beg + 1, '"'); if (end == NULL) continue; *end = '\0'; layout = beg + 1; /* Truncate after first of multiple layouts */ pch = strchr(layout, ','); if (pch != NULL) *pch = '\0'; /* Parse "variant" */ beg = strchr(end + 1, '"'); if (beg == NULL) continue; end = strchr(beg + 1, '"'); if (end == NULL) continue; *end = '\0'; variant = beg + 1; /* Truncate after first of multiple variants */ pch = strchr(variant, ','); if (pch != NULL) *pch = '\0'; } } pclose(xprop); keyboard_layout = find_keyboard_layout_in_xorg_rules(layout, variant); return keyboard_layout; }