Esempio n. 1
0
/*
 * Returns the modifier mask (XCB_MOD_MASK_*) for the given keysymbol, for
 * example for XCB_NUM_LOCK (usually configured to mod2).
 *
 * This function does not initiate any round-trips.
 *
 */
uint32_t get_mod_mask_for(uint32_t keysym,
                          xcb_key_symbols_t *symbols,
                          xcb_get_modifier_mapping_reply_t *modmap_reply) {
    xcb_keycode_t *codes, *modmap;
    xcb_keycode_t mod_code;

    modmap = xcb_get_modifier_mapping_keycodes(modmap_reply);

    /* Get the list of keycodes for the given symbol */
    if (!(codes = xcb_key_symbols_get_keycode(symbols, keysym)))
        return 0;

    /* Loop through all modifiers (Mod1-Mod5, Shift, Control, Lock) */
    for (int mod = 0; mod < 8; mod++)
        for (int j = 0; j < modmap_reply->keycodes_per_modifier; j++) {
            /* Store the current keycode (for modifier 'mod') */
            mod_code = modmap[(mod * modmap_reply->keycodes_per_modifier) + j];
            /* Check if that keycode is in the list of previously resolved
             * keycodes for our symbol. If so, return the modifier mask. */
            for (xcb_keycode_t *code = codes; *code; code++) {
                if (*code != mod_code)
                    continue;

                free(codes);
                /* This corresponds to the XCB_MOD_MASK_* constants */
                return (1 << mod);
            }
        }

    return 0;
}
Esempio n. 2
0
/*
 * Returns the mask for Mode_switch (to be used for looking up keysymbols by
 * keycode).
 *
 */
uint32_t get_mod_mask(xcb_connection_t *conn, uint32_t keycode) {
	xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(conn);

	xcb_get_modifier_mapping_reply_t *modmap_r;
	xcb_keycode_t *modmap, kc;
	xcb_keycode_t *modeswitchcodes = xcb_key_symbols_get_keycode(symbols, keycode);
	if (modeswitchcodes == NULL)
		return 0;

	modmap_r = xcb_get_modifier_mapping_reply(conn, xcb_get_modifier_mapping(conn), NULL);
	modmap = xcb_get_modifier_mapping_keycodes(modmap_r);

	for (int i = 0; i < 8; i++)
		for (int j = 0; j < modmap_r->keycodes_per_modifier; j++) {
			kc = modmap[i * modmap_r->keycodes_per_modifier + j];
			for (xcb_keycode_t *ktest = modeswitchcodes; *ktest; ktest++) {
				if (*ktest != kc)
					continue;

				free(modeswitchcodes);
				free(modmap_r);
				return (1 << i);
			}
		}

	return 0;
}
Esempio n. 3
0
int16_t modfield_from_keysym(xcb_keysym_t keysym)
{
	uint16_t modfield = 0;
	xcb_keycode_t *keycodes = NULL, *mod_keycodes = NULL;
	xcb_get_modifier_mapping_reply_t *reply = NULL;
	xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(dpy);

	if ((keycodes = xcb_key_symbols_get_keycode(symbols, keysym)) == NULL ||
	    (reply = xcb_get_modifier_mapping_reply(dpy, xcb_get_modifier_mapping(dpy), NULL)) == NULL ||
	    reply->keycodes_per_modifier < 1 ||
	    (mod_keycodes = xcb_get_modifier_mapping_keycodes(reply)) == NULL) {
		goto end;
	}

	unsigned int num_mod = xcb_get_modifier_mapping_keycodes_length(reply) / reply->keycodes_per_modifier;
	for (unsigned int i = 0; i < num_mod; i++) {
		for (unsigned int j = 0; j < reply->keycodes_per_modifier; j++) {
			xcb_keycode_t mk = mod_keycodes[i * reply->keycodes_per_modifier + j];
			if (mk == XCB_NO_SYMBOL) {
				continue;
			}
			for (xcb_keycode_t *k = keycodes; *k != XCB_NO_SYMBOL; k++) {
				if (*k == mk) {
					modfield |= (1 << i);
				}
			}
		}
	}

end:
	xcb_key_symbols_free(symbols);
	free(keycodes);
	free(reply);
	return modfield;
}
Esempio n. 4
0
void keyboard::update_mapping( void )
{
	auto cookie = xcb_get_modifier_mapping_unchecked( _connection );
	if ( _keysyms )
		xcb_key_symbols_free( _keysyms );
	_keysyms = xcb_key_symbols_alloc( _connection );

	auto numlockcodes = core::wrap_cptr( xcb_key_symbols_get_keycode( _keysyms, XK_Num_Lock ) );
	auto shiftlockcodes = core::wrap_cptr( xcb_key_symbols_get_keycode( _keysyms, XK_Shift_Lock ) );
	auto capslockcodes = core::wrap_cptr( xcb_key_symbols_get_keycode( _keysyms, XK_Caps_Lock ) );
	auto modeswitchcodes = core::wrap_cptr( xcb_key_symbols_get_keycode( _keysyms, XK_Mode_switch ) );

	auto modmap_r = core::wrap_cptr( xcb_get_modifier_mapping_reply( _connection, cookie, nullptr ) );
	xcb_keycode_t *modmap = xcb_get_modifier_mapping_keycodes( modmap_r.get() );

	_numlock = 0;
	_shiftlock = 0;
	_capslock = 0;
	_modeswitch = 0;

	for( int i = 0; i < 8; i++ )
	{
		for( int j = 0; j < modmap_r->keycodes_per_modifier; j++ )
		{
			xcb_keycode_t kc = modmap[i * modmap_r->keycodes_per_modifier + j];
			look_for( _numlock, numlockcodes, kc, i );
			look_for( _shiftlock, shiftlockcodes, kc, i );
			look_for( _capslock, capslockcodes, kc, i );
			look_for( _modeswitch, modeswitchcodes, kc, i );
		}
	}
}
Esempio n. 5
0
File: xcb.c Progetto: FLYKingdom/vlc
static unsigned GetModifier( xcb_connection_t *p_connection, xcb_key_symbols_t *p_symbols, xcb_keysym_t sym )
{
    static const unsigned pi_mask[8] = {
        XCB_MOD_MASK_SHIFT, XCB_MOD_MASK_LOCK, XCB_MOD_MASK_CONTROL, XCB_MOD_MASK_1,
        XCB_MOD_MASK_2, XCB_MOD_MASK_3, XCB_MOD_MASK_4, XCB_MOD_MASK_5
    };

    const xcb_keycode_t key = xcb_key_symbols_get_keycode( p_symbols, sym );
    if( key == 0 )
        return 0;

    xcb_get_modifier_mapping_cookie_t r = xcb_get_modifier_mapping( p_connection );
    xcb_get_modifier_mapping_reply_t *p_map = xcb_get_modifier_mapping_reply( p_connection, r, NULL );
    if( !p_map )
        return 0;

    xcb_keycode_t *p_keycode = xcb_get_modifier_mapping_keycodes( p_map );
    if( !p_keycode )
        return 0;

    unsigned i_mask = 0;
    for( int i = 0; i < 8; i++ )
    {
        for( int j = 0; j < p_map->keycodes_per_modifier; j++ )
        {
            if( p_keycode[i * p_map->keycodes_per_modifier + j] == key )
                i_mask = pi_mask[i];
        }
    }

    free( p_map ); // FIXME to check
    return i_mask;
}
Esempio n. 6
0
static unsigned GetModifier( xcb_connection_t *p_connection, xcb_key_symbols_t *p_symbols, xcb_keysym_t sym )
{
    static const unsigned pi_mask[8] = {
        XCB_MOD_MASK_SHIFT, XCB_MOD_MASK_LOCK, XCB_MOD_MASK_CONTROL,
        XCB_MOD_MASK_1, XCB_MOD_MASK_2, XCB_MOD_MASK_3,
        XCB_MOD_MASK_4, XCB_MOD_MASK_5
    };

    if( sym == 0 )
        return 0; /* no modifier */

    xcb_get_modifier_mapping_cookie_t r =
            xcb_get_modifier_mapping( p_connection );
    xcb_get_modifier_mapping_reply_t *p_map =
            xcb_get_modifier_mapping_reply( p_connection, r, NULL );
    if( !p_map )
        return 0;

    xcb_keycode_t *p_keys = xcb_key_symbols_get_keycode( p_symbols, sym );
    if( !p_keys )
        goto end;

    int i = 0;
    bool no_modifier = true;
    while( p_keys[i] != XCB_NO_SYMBOL )
    {
        if( p_keys[i] != 0 )
        {
            no_modifier = false;
            break;
        }
        i++;
    }

    if( no_modifier )
        goto end;

    xcb_keycode_t *p_keycode = xcb_get_modifier_mapping_keycodes( p_map );
    if( !p_keycode )
        goto end;

    for( int i = 0; i < 8; i++ )
        for( int j = 0; j < p_map->keycodes_per_modifier; j++ )
            for( int k = 0; p_keys[k] != XCB_NO_SYMBOL; k++ )
                if( p_keycode[i*p_map->keycodes_per_modifier + j] == p_keys[k])
                {
                    free( p_keys );
                    free( p_map );
                    return pi_mask[i];
                }

end:
    free( p_keys );
    free( p_map ); // FIXME to check
    return 0;
}
Esempio n. 7
0
/*
 * Finds out which modifier mask is the one for numlock, as the user may change this.
 *
 */
void xcb_get_numlock_mask(xcb_connection_t *conn) {
    xcb_key_symbols_t *keysyms;
    xcb_get_modifier_mapping_cookie_t cookie;
    xcb_get_modifier_mapping_reply_t *reply;
    xcb_keycode_t *modmap;
    int mask, i;
    const int masks[8] = { XCB_MOD_MASK_SHIFT,
                           XCB_MOD_MASK_LOCK,
                           XCB_MOD_MASK_CONTROL,
                           XCB_MOD_MASK_1,
                           XCB_MOD_MASK_2,
                           XCB_MOD_MASK_3,
                           XCB_MOD_MASK_4,
                           XCB_MOD_MASK_5 };

    /* Request the modifier map */
    cookie = xcb_get_modifier_mapping_unchecked(conn);

    /* Get the keysymbols */
    keysyms = xcb_key_symbols_alloc(conn);

    if ((reply = xcb_get_modifier_mapping_reply(conn, cookie, NULL)) == NULL) {
        xcb_key_symbols_free(keysyms);
        return;
    }

    modmap = xcb_get_modifier_mapping_keycodes(reply);

    /* Get the keycode for numlock */
#ifdef OLD_XCB_KEYSYMS_API
    xcb_keycode_t numlock = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK);
#else
    /* For now, we only use the first keysymbol. */
    xcb_keycode_t *numlock_syms = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK);
    if (numlock_syms == NULL)
        return;
    xcb_keycode_t numlock = *numlock_syms;
    free(numlock_syms);
#endif

    /* Check all modifiers (Mod1-Mod5, Shift, Control, Lock) */
    for (mask = 0; mask < 8; mask++)
        for (i = 0; i < reply->keycodes_per_modifier; i++)
            if (modmap[(mask * reply->keycodes_per_modifier) + i] == numlock)
                xcb_numlock_mask = masks[mask];

    xcb_key_symbols_free(keysyms);
    free(reply);
}
XRecordKeyboardMonitor::XRecordKeyboardMonitor(Display *display)
    : m_connection(xcb_connect(XDisplayString(display), 0)),
      m_modifiersPressed(0), m_keysPressed(0)
{
    if (!m_connection) {
        return;
    }

    xcb_get_modifier_mapping_cookie_t modmapCookie =
        xcb_get_modifier_mapping(m_connection);

    m_context = xcb_generate_id(m_connection);
    xcb_record_range_t range;
    memset(&range, 0, sizeof(range));
    range.device_events.first = XCB_KEY_PRESS;
    range.device_events.last = XCB_KEY_RELEASE;
    xcb_record_client_spec_t cs = XCB_RECORD_CS_ALL_CLIENTS;
    xcb_record_create_context(m_connection, m_context, 0, 1, 1, &cs, &range);
    xcb_flush(m_connection);

    QScopedPointer<xcb_get_modifier_mapping_reply_t, QScopedPointerPodDeleter>
    modmap(xcb_get_modifier_mapping_reply(m_connection, modmapCookie, 0));
    if (!modmap) {
        return;
    }

    int nModifiers = xcb_get_modifier_mapping_keycodes_length(modmap.data());
    xcb_keycode_t *modifiers = xcb_get_modifier_mapping_keycodes(modmap.data());
    m_modifier.fill(false, std::numeric_limits<xcb_keycode_t>::max() + 1);
    for (xcb_keycode_t *i = modifiers; i < modifiers + nModifiers; i++) {
        m_modifier[*i] = true;
    }
    m_ignore.fill(false, std::numeric_limits<xcb_keycode_t>::max() + 1);
    for (xcb_keycode_t *i = modifiers;
            i < modifiers + modmap->keycodes_per_modifier; i++)
    {
        m_ignore[*i] = true;
    }
    m_pressed.fill(false, std::numeric_limits<xcb_keycode_t>::max() + 1);

    m_cookie = xcb_record_enable_context(m_connection, m_context);
    xcb_flush(m_connection);

    m_notifier = new QSocketNotifier(xcb_get_file_descriptor(m_connection),
                                     QSocketNotifier::Read, this);
    connect(m_notifier, SIGNAL(activated(int)), SLOT(processNextReply()));
    m_notifier->setEnabled(true);
}
Esempio n. 9
0
File: nilwm.c Progetto: nqv/nilwm
static
void update_keys_mask() {
    xcb_keycode_t key_num, key_shift, key_caps, key_mode, key;
    xcb_get_modifier_mapping_reply_t *reply;
    xcb_keycode_t *codes;
    unsigned int i, j;

    nil_.mask_numlock    = 0;
    nil_.mask_shiftlock  = 0;
    nil_.mask_capslock   = 0;
    nil_.mask_modeswitch = 0;
    key_num   = get_keycode(XK_Num_Lock);
    key_shift = get_keycode(XK_Shift_Lock);
    key_caps  = get_keycode(XK_Caps_Lock);
    key_mode  = get_keycode(XK_Mode_switch);

    reply = xcb_get_modifier_mapping_reply(nil_.con,
        xcb_get_modifier_mapping_unchecked(nil_.con), 0);
    codes = xcb_get_modifier_mapping_keycodes(reply);

    /* The number of keycodes in the list is 8 * keycodes_per_modifier */
    for (i = 0; i < 8; ++i) {
        for (j = 0; j < reply->keycodes_per_modifier; ++j) {
            key = codes[i * reply->keycodes_per_modifier + j];
            if (!key) {
                continue;
            }
            if (key == key_num) {
                nil_.mask_numlock = (uint16_t)(1 << i);
            } else if (key == key_shift) {
                nil_.mask_shiftlock = (uint16_t)(1 << i);
            } else if (key == key_caps) {
                nil_.mask_capslock = (uint16_t)(1 << i);
            } else if (key == key_mode) {
                nil_.mask_modeswitch = (uint16_t)(1 << i);
            }
        }
    }
    NIL_LOG("mask num=0x%x shift=0x%x caps=0x%x mode=0x%x", nil_.mask_numlock,
        nil_.mask_shiftlock, nil_.mask_capslock, nil_.mask_modeswitch);
    free(reply);
}
Esempio n. 10
0
void App::keyRelease(const xcb_key_release_event_t* event)
{
    unsigned int mk = event->state & USED_MASK;
    // ev.state is state before the key release, so just checking mk being 0 isn't enough
    // using XQueryPointer() also doesn't seem to work well, so the check that all
    // modifiers are released: only one modifier is active and the currently released
    // key is this modifier - if yes, release the grab
    int mod_index = -1;
    for (int i = XCB_MAP_INDEX_SHIFT;
             i <= XCB_MAP_INDEX_5;
             ++i)
        if ((mk & (1 << i)) != 0) {
            if (mod_index >= 0)
                return;
            mod_index = i;
        }
    bool release = false;
    if (mod_index == -1)
        release = true;
    else {
        auto cookie = xcb_get_modifier_mapping(QX11Info::connection());
        auto reply = xcb_get_modifier_mapping_reply(QX11Info::connection(), cookie, NULL);
        if (reply) {
            auto keycodes = xcb_get_modifier_mapping_keycodes(reply);
            for (int i = 0; i < reply->keycodes_per_modifier; i++) {
                if (keycodes[reply->keycodes_per_modifier * mod_index + i]
                        == event->detail) {
                    release = true;
                }
            }
        }
        free(reply);
    }
    if (!release) {
        return;
    }
    if (m_keyboardGrabbed) {
        accept();
    }
}
Esempio n. 11
0
File: main.c Progetto: stfnm/i3
static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) {
    printf("Keypress %d, state raw = %d\n", event->detail, event->state);

    /* Remove the numlock bit, all other bits are modifiers we can bind to */
    uint16_t state_filtered = event->state & ~(xcb_numlock_mask | XCB_MOD_MASK_LOCK);
    /* Only use the lower 8 bits of the state (modifier masks) so that mouse
     * button masks are filtered out */
    state_filtered &= 0xFF;

    xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, state_filtered);

    printf("sym = %c (%d)\n", sym, sym);

    if (sym == XK_Return || sym == XK_KP_Enter) {
        if (current_step == STEP_WELCOME) {
            current_step = STEP_GENERATE;
            /* Set window title */
            xcb_change_property(conn,
                XCB_PROP_MODE_REPLACE,
                win,
                A__NET_WM_NAME,
                A_UTF8_STRING,
                8,
                strlen("i3: generate config"),
                "i3: generate config");
            xcb_flush(conn);
        }
        else finish();
    }

    /* cancel any time */
    if (sym == XK_Escape)
        exit(0);

    /* Check if this is Mod1 or Mod4. The modmap contains Shift, Lock, Control,
     * Mod1, Mod2, Mod3, Mod4, Mod5 (in that order) */
    xcb_keycode_t *modmap = xcb_get_modifier_mapping_keycodes(modmap_reply);
    /* Mod1? */
    int mask = 3;
    for (int i = 0; i < modmap_reply->keycodes_per_modifier; i++) {
        xcb_keycode_t code = modmap[(mask * modmap_reply->keycodes_per_modifier) + i];
        if (code == XCB_NONE)
            continue;
        printf("Modifier keycode for Mod1: 0x%02x\n", code);
        if (code == event->detail) {
            modifier = MOD_Mod1;
            printf("This is Mod1!\n");
        }
    }

    /* Mod4? */
    mask = 6;
    for (int i = 0; i < modmap_reply->keycodes_per_modifier; i++) {
        xcb_keycode_t code = modmap[(mask * modmap_reply->keycodes_per_modifier) + i];
        if (code == XCB_NONE)
            continue;
        printf("Modifier keycode for Mod4: 0x%02x\n", code);
        if (code == event->detail) {
            modifier = MOD_Mod4;
            printf("This is Mod4!\n");
        }
    }

    handle_expose();
    return 1;
}
// http://svn.tribler.org/vlc/trunk/modules/control/globalhotkeys/xcb.c
// Copyright (C) 2009 the VideoLAN team
static unsigned GetModifier( xcb_connection_t *p_connection, xcb_key_symbols_t *p_symbols, xcb_keysym_t sym )
{
    static const unsigned pi_mask[8] = {
        XCB_MOD_MASK_SHIFT, XCB_MOD_MASK_LOCK, XCB_MOD_MASK_CONTROL,
        XCB_MOD_MASK_1, XCB_MOD_MASK_2, XCB_MOD_MASK_3,
        XCB_MOD_MASK_4, XCB_MOD_MASK_5
    };

    if( sym == 0 )
        return 0; /* no modifier */

#ifdef XCB_KEYSYM_OLD_API /* as seen in Debian Lenny */
    const xcb_keycode_t key = xcb_key_symbols_get_keycode( p_symbols, sym );
    if( key == 0 )
        return 0;
#else
    const xcb_keycode_t *p_keys = xcb_key_symbols_get_keycode( p_symbols, sym );
    if( !p_keys )
        return 0;

    int i = 0;
    bool no_modifier = true;
    while( p_keys[i] != XCB_NO_SYMBOL )
    {
        if( p_keys[i] != 0 )
        {
            no_modifier = false;
            break;
        }
        i++;
    }

    if( no_modifier )
        return 0;
#endif

    xcb_get_modifier_mapping_cookie_t r =
            xcb_get_modifier_mapping( p_connection );
    xcb_get_modifier_mapping_reply_t *p_map =
            xcb_get_modifier_mapping_reply( p_connection, r, NULL );
    if( !p_map )
        return 0;

    xcb_keycode_t *p_keycode = xcb_get_modifier_mapping_keycodes( p_map );
    if( !p_keycode )
        return 0;

    for( int i = 0; i < 8; i++ )
        for( int j = 0; j < p_map->keycodes_per_modifier; j++ )
#ifdef XCB_KEYSYM_OLD_API /* as seen in Debian Lenny */
            if( p_keycode[i * p_map->keycodes_per_modifier + j] == key )
            {
                free( p_map );
                return pi_mask[i];
            }
#else
            for( int k = 0; p_keys[k] != XCB_NO_SYMBOL; k++ )
                if( p_keycode[i*p_map->keycodes_per_modifier + j] == p_keys[k])
                {
                    free( p_map );
                    return pi_mask[i];
                }
#endif

    free( p_map ); // FIXME to check
    return 0;
}