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; }
XkbRF_RulesPtr tryLoadRules(char *name, char *locale, Bool wantDesc, Bool wantRules) { XkbRF_RulesPtr rules = NULL; VMSG1(7, "Trying to load rules file %s...\n", name); rules = XkbRF_Load(name, locale, wantDesc, wantRules); if (rules) { VMSG(7, "Success.\n"); } return rules; }
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); }
static XkbRF_RulesPtr fetch_all_layouts(const String ¤t) { char buf[256]; XkbRF_RulesPtr xkb_rules = NULL; XkbRF_DescribeVarsPtr layouts = NULL; /* try to locate rules file */ for(int i = 0; x11_dirs[i]; i++) { for(int j = 0; x11_rules[j]; j++) { snprintf(buf, sizeof(buf), "%s%s", x11_dirs[i], x11_rules[j]); xkb_rules = XkbRF_Load(buf, (char*)"", True, True); if(xkb_rules) goto done; } } if(!xkb_rules) { E_WARNING(E_STRLOC ": Unable to load keyboard rules file\n"); return NULL; } done: layouts = &xkb_rules->layouts; /* sort them */ qsort(layouts->desc, layouts->num_desc, sizeof(XkbRF_VarDescRec), sort_cmp); for(int i = 0; i < layouts->num_desc; i++) { snprintf(buf, sizeof(buf), "%s\t%s", layouts->desc[i].name, layouts->desc[i].desc); layout_browser->add(buf); if(current == layouts->desc[i].name) { /* Fl_Browser counts items from 1 */ layout_browser->select(i + 1); } } return xkb_rules; }
RulesInfo* X11Helper::loadRules(const TQString& file, bool layoutsOnly) { XkbRF_RulesPtr xkbRules = XkbRF_Load(TQFile::encodeName(file).data(), "", true, true); if (xkbRules == NULL) { // throw Exception return NULL; } RulesInfo* rulesInfo = new RulesInfo(); for (int i = 0; i < xkbRules->layouts.num_desc; ++i) { TQString layoutName(xkbRules->layouts.desc[i].name); rulesInfo->layouts.replace( layoutName, tqstrdup( xkbRules->layouts.desc[i].desc ) ); if( m_layoutsClean == true && layoutName.find( NON_CLEAN_LAYOUT_REGEXP ) != -1 && layoutName.endsWith("/jp") == false ) { kdDebug() << "Layouts are not clean (Xorg < 6.9.0 or XFree86)" << endl; m_layoutsClean = false; } } if( layoutsOnly == true ) { XkbRF_Free(xkbRules, true); return rulesInfo; } for (int i = 0; i < xkbRules->models.num_desc; ++i) rulesInfo->models.replace(xkbRules->models.desc[i].name, tqstrdup( xkbRules->models.desc[i].desc ) ); for (int i = 0; i < xkbRules->options.num_desc; ++i) rulesInfo->options.replace(xkbRules->options.desc[i].name, tqstrdup( xkbRules->options.desc[i].desc ) ); XkbRF_Free(xkbRules, true); // workaround for empty 'compose' options group description if( rulesInfo->options.find("compose:menu") && !rulesInfo->options.find("compose") ) { rulesInfo->options.replace("compose", "Compose Key Position"); } for(TQDictIterator<char> it(rulesInfo->options) ; it.current() != NULL; ++it ) { TQString option(it.currentKey()); int columnPos = option.find(":"); if( columnPos != -1 ) { TQString group = option.mid(0, columnPos); if( rulesInfo->options.find(group) == NULL ) { rulesInfo->options.replace(group, group.latin1()); kdDebug() << "Added missing option group: " << group << endl; } } } // // workaround for empty misc options group description in XFree86 4.4.0 // if( rulesInfo->options.find("numpad:microsoft") && !rulesInfo->options.find("misc") ) { // rulesInfo->options.replace("misc", "Miscellaneous compatibility options" ); // } return rulesInfo; }
/** * 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; }