void KeyboardLayoutWidget::setKeyboardLayout(const QString& layout, const QString& variant) { XkbRF_VarDefsRec rdefs; XkbComponentNamesRec rnames; QString rulesPath = "./rules/evdev"; char c[] = "C"; XkbRF_RulesPtr rules = XkbRF_Load (rulesPath.toLocal8Bit().data(), c, True, True); if (rules == NULL) { rulesPath = FcitxXkbFindXkbRulesFile(); if (rulesPath.endsWith(".xml")) { rulesPath.chop(4); } rules = XkbRF_Load (rulesPath.toLocal8Bit().data(), c, True, True); } if (rules == NULL) { return; } memset (&rdefs, 0, sizeof (XkbRF_VarDefsRec)); memset (&rnames, 0, sizeof (XkbComponentNamesRec)); QString model, option; if (!FcitxXkbInitDefaultOption(model, option)) return; rdefs.model = !model.isNull() ? strdup(model.toUtf8().constData()) : NULL; rdefs.layout = !layout.isNull() ? strdup(layout.toUtf8().constData()) : NULL; rdefs.variant = !variant.isNull() ? strdup(variant.toUtf8().constData()) : NULL; rdefs.options = !option.isNull() ? strdup(option.toUtf8().constData()) : NULL; XkbRF_GetComponents (rules, &rdefs, &rnames); free (rdefs.model); free (rdefs.layout); free (rdefs.variant); free (rdefs.options); setKeyboard(&rnames); }
/* * Use XKB extension and libxkbfile to discover the type of keycodes * generated by the X keyboard */ const char *get_xkb_keycodes (Display *display) { char *result = 0; char *rulesfile = 0; int32_t major = XkbMajorVersion; int32_t minor = XkbMinorVersion; int32_t error = 0; XkbRF_VarDefsRec vd; if (!XkbLibraryVersion (&major, &minor)) { write_log ("X11GFX: Xkb version conflict!\n"); return 0; } if (!XkbQueryExtension (display, 0, 0, &error, &major, &minor)) { printf ("X11GFX: XKB error: %d\n", error); return 0; } if (XkbRF_GetNamesProp (display, &rulesfile, &vd) && rulesfile != 0) { if (rulesfile[0] == '/') { char *tmp = malloc (strlen (rulesfile)); if (tmp) { strcpy (tmp, rulesfile); rulesfile = tmp; } } else { char *tmp = malloc (strlen (xkb_rules_path) + strlen (rulesfile) + 1); if (tmp) { strcpy (tmp, xkb_rules_path); strcat (tmp, rulesfile); rulesfile = tmp; } } } if (rulesfile) { XkbRF_RulesPtr rules; if ((rules = XkbRF_Load (rulesfile, 0, True, True))) { XkbComponentNamesRec names; XkbRF_GetComponents (rules, &vd, &names); if (names.keycodes) result = names.keycodes; } } return result; }
Bool XkbDDXNamesFromRules( DeviceIntPtr keybd, char * rules_name, XkbRF_VarDefsPtr defs, XkbComponentNamesPtr names) { char buf[PATH_MAX]; FILE * file; Bool complete; XkbRF_RulesPtr rules; if (!rules_name) return FALSE; if (strlen(XkbBaseDirectory) + strlen(rules_name) + 8 > PATH_MAX) { LogMessage(X_ERROR, "XKB: Rules name is too long\n"); return FALSE; } sprintf(buf,"%s/rules/%s", XkbBaseDirectory, rules_name); file = fopen(buf, "r"); if (!file) { LogMessage(X_ERROR, "XKB: Couldn't open rules file %s\n", buf); return FALSE; } rules = XkbRF_Create(); if (!rules) { LogMessage(X_ERROR, "XKB: Couldn't create rules struct\n"); fclose(file); return FALSE; } if (!XkbRF_LoadRules(file, rules)) { LogMessage(X_ERROR, "XKB: Couldn't parse rules file %s\n", rules_name); fclose(file); XkbRF_Free(rules,TRUE); return FALSE; } memset(names, 0, sizeof(*names)); complete = XkbRF_GetComponents(rules,defs,names); fclose(file); XkbRF_Free(rules, TRUE); if (!complete) LogMessage(X_ERROR, "XKB: Rules returned no components\n"); return complete; }
Bool XkbDDXNamesFromRules( DeviceIntPtr keybd, char * rules_name, XkbRF_VarDefsPtr defs, XkbComponentNamesPtr names) { char buf[PATH_MAX]; FILE * file; Bool complete; XkbRF_RulesPtr rules; if (!rules_name) return False; if (XkbBaseDirectory==NULL) { if (strlen(rules_name)+7 > PATH_MAX) return False; sprintf(buf,"rules/%s",rules_name); } else { if (strlen(XkbBaseDirectory)+strlen(rules_name)+8 > PATH_MAX) return False; sprintf(buf,"%s/rules/%s",XkbBaseDirectory,rules_name); } if ((file= fopen(buf,"r"))==NULL) return False; if ((rules= XkbRF_Create(0,0))==NULL) { fclose(file); return False; } if (!XkbRF_LoadRules(file,rules)) { fclose(file); XkbRF_Free(rules,True); return False; } bzero((char *)names,sizeof(XkbComponentNamesRec)); complete= XkbRF_GetComponents(rules,defs,names); fclose(file); XkbRF_Free(rules,True); return complete; }
static void apply_keymap (MetaBackendX11 *x11) { MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); XkbRF_RulesRec *xkb_rules; XkbRF_VarDefsRec xkb_var_defs = { 0 }; gchar *rules_file_path; if (!priv->keymap_layouts || !priv->keymap_variants || !priv->keymap_options) return; get_xkbrf_var_defs (priv->xdisplay, priv->keymap_layouts, priv->keymap_variants, priv->keymap_options, &rules_file_path, &xkb_var_defs); xkb_rules = XkbRF_Load (rules_file_path, NULL, True, True); if (xkb_rules) { XkbComponentNamesRec xkb_comp_names = { 0 }; XkbRF_GetComponents (xkb_rules, &xkb_var_defs, &xkb_comp_names); upload_xkb_description (priv->xdisplay, rules_file_path, &xkb_var_defs, &xkb_comp_names); free_xkb_component_names (&xkb_comp_names); XkbRF_Free (xkb_rules, True); } else { g_warning ("Couldn't load XKB rules"); } free_xkbrf_var_defs (&xkb_var_defs); g_free (rules_file_path); }
/** * If any of model, layout, variant or options is specified, then compile the * options into the * * @return True on success or false otherwise. */ Bool applyRules(void) { int i; char *rfName; if (settings.model.src || settings.layout.src || settings.variant.src || options.item) { char buf[PATH_MAX]; XkbComponentNamesRec rnames; if (settings.variant.src < settings.layout.src) settings.variant.value = NULL; rdefs.model = settings.model.value; rdefs.layout = settings.layout.value; rdefs.variant = settings.variant.value; if (options.item) rdefs.options = stringFromOptions(rdefs.options, &options); if (settings.rules.src) rfName = settings.rules.value; else rfName = DFLT_XKB_RULES_FILE; if (rfName[0] == '/') { rules = tryLoadRules(rfName, settings.locale.value, True, True); } else { /* try to load rules files from all include paths until the first * we succeed with */ for (i = 0; (i < inclPath.num) && (!rules); i++) { if (snprintf(buf, PATH_MAX, "%s/rules/%s", inclPath.item[i], rfName) >= PATH_MAX) { VMSG2(0, "Path too long (%s/rules/%s). Ignored.\n", inclPath.item[i], rfName); continue; } rules = tryLoadRules(buf, settings.locale.value, True, True); } } if (!rules) { ERR1("Couldn't find rules file (%s) \n", rfName); return False; } /* Let the rules file to the magic, then update the svValues with * those returned after processing the rules */ XkbRF_GetComponents(rules, &rdefs, &rnames); if (rnames.keycodes) { trySetString(&settings.keycodes, rnames.keycodes, FROM_RULES); rnames.keycodes = NULL; } if (rnames.symbols) { trySetString(&settings.symbols, rnames.symbols, FROM_RULES); rnames.symbols = NULL; } if (rnames.types) { trySetString(&settings.types, rnames.types, FROM_RULES); rnames.types = NULL; } if (rnames.compat) { trySetString(&settings.compat, rnames.compat, FROM_RULES); rnames.compat = NULL; } if (rnames.geometry) { trySetString(&settings.geometry, rnames.geometry, FROM_RULES); rnames.geometry = NULL; } if (rnames.keymap) { trySetString(&settings.keymap, rnames.keymap, FROM_RULES); rnames.keymap = NULL; } if (verbose > 6) { MSG1("Applied rules from %s:\n", rfName); dumpNames(True, False); } } else if (verbose > 6) { MSG("No rules variables specified. Rules file ignored\n"); } return True; }
/** * If any of model, layout, variant or options is specified, then compile the * options into the * * @return True on success or false otherwise. */ Bool applyRules(void) { int i; char *rfName; if (svSrc[MODEL_NDX] || svSrc[LAYOUT_NDX] || svSrc[VARIANT_NDX] || options) { char buf[PATH_MAX]; XkbComponentNamesRec rnames; if (svSrc[VARIANT_NDX] < svSrc[LAYOUT_NDX]) svValue[VARIANT_NDX] = NULL; rdefs.model = svValue[MODEL_NDX]; rdefs.layout = svValue[LAYOUT_NDX]; rdefs.variant = svValue[VARIANT_NDX]; if (options) rdefs.options = stringFromOptions(rdefs.options, numOptions, options); if (svSrc[RULES_NDX]) rfName = svValue[RULES_NDX]; else rfName = DFLT_XKB_RULES_FILE; if (rfName[0] == '/') { rules = XkbRF_Load(rfName, svValue[LOCALE_NDX], True, True); } else { /* try to load rules files from all include paths until the first * we succeed with */ for (i = 0; (i < numInclPath) && (!rules); i++) { if ((strlen(inclPath[i]) + strlen(rfName) + 8) > PATH_MAX) { VMSG2(0, "Path too long (%s/rules/%s). Ignored.\n", inclPath[i], rfName); continue; } sprintf(buf, "%s/rules/%s", inclPath[i], svValue[RULES_NDX]); rules = XkbRF_Load(buf, svValue[LOCALE_NDX], True, True); } } if (!rules) { ERR1("Couldn't find rules file (%s) \n", svValue[RULES_NDX]); return False; } /* Let the rules file to the magic, then update the svValues with * those returned after processing the rules */ XkbRF_GetComponents(rules, &rdefs, &rnames); if (rnames.keycodes) { trySetString(KEYCODES_NDX, rnames.keycodes, FROM_RULES); rnames.keycodes = NULL; } if (rnames.symbols) { trySetString(SYMBOLS_NDX, rnames.symbols, FROM_RULES); rnames.symbols = NULL; } if (rnames.types) { trySetString(TYPES_NDX, rnames.types, FROM_RULES); rnames.types = NULL; } if (rnames.compat) { trySetString(COMPAT_NDX, rnames.compat, FROM_RULES); rnames.compat = NULL; } if (rnames.geometry) { trySetString(GEOMETRY_NDX, rnames.geometry, FROM_RULES); rnames.geometry = NULL; } if (rnames.keymap) { trySetString(KEYMAP_NDX, rnames.keymap, FROM_RULES); rnames.keymap = NULL; } if (verbose > 6) { MSG1("Applied rules from %s:\n", svValue[RULES_NDX]); dumpNames(True, False); } } else if (verbose > 6) { MSG("No rules variables specified. Rules file ignored\n"); } return True; }