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);
}
Example #2
0
/*
 * 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;
}
Example #3
0
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;
}
Example #4
0
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);
}
Example #5
0
static XkbRF_RulesPtr fetch_all_layouts(const String &current) {
	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;
}
Example #6
0
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;
}
Example #7
0
/**
 * 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;
}