Beispiel #1
0
void init_modifier_keys() {
    int i, k = 0;
    int min_keycode, max_keycode, keysyms_per_keycode = 0;

    std::list<KeySym> Mod1MaskSyms, Mod2MaskSyms, Mod3MaskSyms,
		      Mod4MaskSyms, Mod5MaskSyms;

    gXNumLockMask = 0;
    XModifierKeymap *map = XGetModifierMapping(XimServer::gDpy);
    XDisplayKeycodes(XimServer::gDpy, &min_keycode, &max_keycode);
    KeySym *sym = XGetKeyboardMapping(XimServer::gDpy,
                    static_cast<KeyCode>(min_keycode),
                    (max_keycode - min_keycode + 1), &keysyms_per_keycode);
    for (i = 0; i < 8; i++) {
	int j;
	for (j = 0; j < map->max_keypermod; j++) {
	    if (map->modifiermap[k]) {
		KeySym ks;
		int index = 0;
		do {
		    ks = XkbKeycodeToKeysym(XimServer::gDpy,
				    map->modifiermap[k], 0, index);
		    index++;
		} while (!ks && index < keysyms_per_keycode);

		switch (i) {
		case ShiftMapIndex: break;
		case LockMapIndex: break;
		case ControlMapIndex: break;
		case Mod1MapIndex: Mod1MaskSyms.push_back(ks); break;
		case Mod2MapIndex: Mod2MaskSyms.push_back(ks); break;
		case Mod3MapIndex: Mod3MaskSyms.push_back(ks); break;
		case Mod4MapIndex: Mod4MaskSyms.push_back(ks); break;
		case Mod5MapIndex: Mod5MaskSyms.push_back(ks); break;
		default: break;
		}
		// Check NumLock key
		if (ks == XK_Num_Lock)
		    gXNumLockMask |= (1 << i);
	    }
	    k++;
	}
    }
    XFreeModifiermap(map);
    XFree(sym);

    gMod1Mask = check_modifier(Mod1MaskSyms);
    gMod2Mask = check_modifier(Mod2MaskSyms);
    gMod3Mask = check_modifier(Mod3MaskSyms);
    gMod4Mask = check_modifier(Mod4MaskSyms);
    gMod5Mask = check_modifier(Mod5MaskSyms);

    if (uim_scm_c_bool(uim_scm_callf("require-dynlib", "s", "xkb")))
	uim_scm_callf("%xkb-set-display", "p", XimServer::gDpy);

#if UIM_XIM_USE_JAPANESE_KANA_KEYBOARD_HACK
    // Init at here to sync with proper update timing although not a modifier.
    uim_x_kana_input_hack_init(XimServer::gDpy);
#endif
}
Beispiel #2
0
/*!
 * \param[in,out] sc     Selection collection to registered the method to.
 * \param[in]     name   Name under which the method should be registered.
 * \param[in]     method Method to register.
 * \returns       0 on success, EINVAL if there was something wrong with the
 *   method.
 *
 * \p name does not need to match the name of the method, and the same
 * method can be registered multiple times under different names.
 * If \p name equals some previously registered name,
 * an error message is printed and the method is not registered.
 *
 * The function also performs some sanity checking on the input method,
 * and refuses to register it if there are problems.
 * Some problems only generate warnings.
 * All problems are described to \p stderr.
 */
int
gmx_ana_selmethod_register(struct gmx_ana_selcollection_t *sc,
                           const char *name, gmx_ana_selmethod_t *method)
{
    gmx_bool bOk;

    /* Check the method */
    if (method->flags & SMETH_MODIFIER)
    {
        bOk = check_modifier(stderr, method, sc->symtab);
    }
    else
    {
        bOk = check_method(stderr, method, sc->symtab);
    }
    /* Try to register the method if everything is ok */
    if (bOk)
    {
        if (!_gmx_sel_add_method_symbol(sc->symtab, name, method))
        {
            bOk = FALSE;
        }
    }
    if (!bOk)
    {
        report_error(stderr, name, "warning: not registered");
        return EINVAL;
    }
    return 0;
}
Beispiel #3
0
/*!
 * \param[in,out] symtab Symbol table to register the method to.
 * \param[in]     name   Name under which the method should be registered.
 * \param[in]     method Method to register.
 * \returns       0 on success, -1 if there was something wrong with the
 *   method.
 *
 * \p name does not need to match the name of the method, and the same
 * method can be registered multiple times under different names.
 * If \p name equals some previously registered name,
 * an error message is printed and the method is not registered.
 *
 * The function also performs some sanity checking on the input method,
 * and refuses to register it if there are problems.
 * Some problems only generate warnings.
 * All problems are described to \p stderr.
 */
int
gmx_ana_selmethod_register(gmx::SelectionParserSymbolTable *symtab,
                           const char *name, gmx_ana_selmethod_t *method)
{
    bool bOk;

    /* Check the method */
    if (method->flags & SMETH_MODIFIER)
    {
        bOk = check_modifier(stderr, method, *symtab);
    }
    else
    {
        bOk = check_method(stderr, method, *symtab);
    }
    /* Try to register the method if everything is ok */
    if (bOk)
    {
        try
        {
            symtab->addMethod(name, method);
        }
        catch (const gmx::APIError &ex)
        {
            report_error(stderr, name, ex.what());
            bOk = false;
        }
    }
    if (!bOk)
    {
        report_error(stderr, name, "warning: not registered");
        return -1;
    }
    return 0;
}
Beispiel #4
0
static void x_reset_modifier_mapping(Display * display)
{
	int modifier_index, modifier_key, column, mkpm;
	int meta_bit = 0;
	int hyper_bit = 0;
	int super_bit = 0;
	int alt_bit = 0;
	int mode_bit = 0;
	XModifierKeymap *x_modifier_keymap;

#define modwarn(name,old,other)							\
    wwarning(_("%s (0x%x) generates %s which is generated by %s"),		\
    name, code, index_to_name (old), other)

#define modbarf(name,other)							\
    wwarning(_("%s (0x%x) generates %s which is nonsensical"),			\
    name, code, other)

#define check_modifier(name,mask)						\
    if ((1<<modifier_index) != mask)						\
    wwarning(_("%s (0x%x) generates %s which is nonsensical"),			\
    name, code, index_to_name (modifier_index))

#define store_modifier(name,old)						\
    if (old && old != modifier_index)						\
    wwarning(_("%s (0x%x) generates both %s and %s which is nonsensical"),	\
    name, code, index_to_name (old),						\
    index_to_name (modifier_index));						\
    if (modifier_index == ShiftMapIndex) modbarf (name,"ModShift");		\
    else if (modifier_index == LockMapIndex) modbarf (name,"ModLock");		\
    else if (modifier_index == ControlMapIndex) modbarf (name,"ModControl");	\
    else if (sym == XK_Mode_switch)						\
    mode_bit = modifier_index; /* Mode_switch is special, see below... */	\
    else if (modifier_index == meta_bit && old != meta_bit)			\
    modwarn (name, meta_bit, "Meta");						\
    else if (modifier_index == super_bit && old != super_bit)			\
    modwarn (name, super_bit, "Super");						\
    else if (modifier_index == hyper_bit && old != hyper_bit)			\
    modwarn (name, hyper_bit, "Hyper");						\
    else if (modifier_index == alt_bit && old != alt_bit)			\
    modwarn (name, alt_bit, "Alt");						\
    else									\
    old = modifier_index;

	x_modifier_keymap = XGetModifierMapping(display);
	if (x_modifier_keymap == NULL) {
		wwarning(_("XGetModifierMapping returned NULL, there is no modifier or no memory"));
		return;
	}

	mkpm = x_modifier_keymap->max_keypermod;
	for (modifier_index = 0; modifier_index < 8; modifier_index++)
		for (modifier_key = 0; modifier_key < mkpm; modifier_key++) {
			KeySym last_sym = 0;
			for (column = 0; column < 4; column += 2) {
				KeyCode code = x_modifier_keymap->modifiermap[modifier_index * mkpm
									      + modifier_key];
				KeySym sym;

				if (code) {
					if (xext_xkb_supported)
						sym = XkbKeycodeToKeysym(display, code, 0, column);
					else
						sym = XKeycodeToKeysym(display, code, column);
				} else {
					sym = NoSymbol;
				}

				if (sym == last_sym)
					continue;
				last_sym = sym;
				switch (sym) {
				case XK_Mode_switch:
					store_modifier("Mode_switch", mode_bit);
					break;
				case XK_Meta_L:
					store_modifier("Meta_L", meta_bit);
					break;
				case XK_Meta_R:
					store_modifier("Meta_R", meta_bit);
					break;
				case XK_Super_L:
					store_modifier("Super_L", super_bit);
					break;
				case XK_Super_R:
					store_modifier("Super_R", super_bit);
					break;
				case XK_Hyper_L:
					store_modifier("Hyper_L", hyper_bit);
					break;
				case XK_Hyper_R:
					store_modifier("Hyper_R", hyper_bit);
					break;
				case XK_Alt_L:
					store_modifier("Alt_L", alt_bit);
					break;
				case XK_Alt_R:
					store_modifier("Alt_R", alt_bit);
					break;
				case XK_Control_L:
					check_modifier("Control_L", ControlMask);
					break;
				case XK_Control_R:
					check_modifier("Control_R", ControlMask);
					break;
				case XK_Shift_L:
					check_modifier("Shift_L", ShiftMask);
					break;
				case XK_Shift_R:
					check_modifier("Shift_R", ShiftMask);
					break;
				case XK_Shift_Lock:
					check_modifier("Shift_Lock", LockMask);
					break;
				case XK_Caps_Lock:
					check_modifier("Caps_Lock", LockMask);
					break;

					/* It probably doesn't make any sense for a modifier bit to be
					   assigned to a key that is not one of the above, but OpenWindows
					   assigns modifier bits to a couple of random function keys for
					   no reason that I can discern, so printing a warning here would
					   be annoying. */
				}
			}
		}
#undef store_modifier
#undef check_modifier
#undef modwarn
#undef modbarf

	/* If there was no Meta key, then try using the Alt key instead.
	   If there is both a Meta key and an Alt key, then the Alt key
	   is not disturbed and remains an Alt key. */
	if (!meta_bit && alt_bit)
		meta_bit = alt_bit, alt_bit = 0;

	/* mode_bit overrides everything, since it's processed down inside of
	   XLookupString() instead of by us.  If Meta and Mode_switch both
	   generate the same modifier bit (which is an error), then we don't
	   interpret that bit as Meta, because we can't make XLookupString()
	   not interpret it as Mode_switch; and interpreting it as both would
	   be totally wrong. */
	if (mode_bit) {
		const char *warn = 0;
		if (mode_bit == meta_bit)
			warn = "Meta", meta_bit = 0;
		else if (mode_bit == hyper_bit)
			warn = "Hyper", hyper_bit = 0;
		else if (mode_bit == super_bit)
			warn = "Super", super_bit = 0;
		else if (mode_bit == alt_bit)
			warn = "Alt", alt_bit = 0;
		if (warn) {
			wwarning(_("%s is being used for both %s and %s"),
			         index_to_name(mode_bit), "Mode_switch", warn);
		}
	}

	MetaIndex = meta_bit;
	HyperIndex = hyper_bit;
	SuperIndex = super_bit;
	AltIndex = alt_bit;
	ModeIndex = mode_bit;

	XFreeModifiermap(x_modifier_keymap);
}